From a571e6e6e5344cd6524134ea60f4cfa26dad5a49 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 7 Jul 2022 19:44:33 +0200 Subject: [PATCH 1/2] Recover unfinished binary expressions --- src/Compiler/SyntaxTree/LexFilter.fs | 47 ++++++++++++++++++++++++++-- src/Compiler/pars.fsy | 40 +++++++++++------------ 2 files changed, 65 insertions(+), 22 deletions(-) diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index 9b54f1c9976..705a16c25a7 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -181,7 +181,49 @@ let infixTokenLength token = | INFIX_STAR_STAR_OP d -> d.Length | COLON_QMARK_GREATER -> 3 | _ -> assert false; 1 - + +let canFollowInfixToken token = + match token with + | ABSTRACT + | AND + | AND_BANG _ + | AS + | DONE + | DOWNTO + | ELIF + | ELSE + | END + | EXCEPTION + | EXTERN + | FINALLY + | IN + | INHERIT + | INLINE + | INTERFACE + | INTERNAL + | MEMBER + | MODULE + | MUTABLE + | NAMESPACE + | OF + | OPEN + | OR + | OVERRIDE + | PRIVATE + | PUBLIC + | REC + | STATIC + | THEN + | TO + | TYPE + | VAL + | VOID + | WHEN + | WITH + + | LBRACK_LESS -> false + | _ -> true + /// Matches against a left-parenthesis-like token that is valid in expressions. // // LBRACK_LESS and GREATER_RBRACK are not here because adding them in these active patterns @@ -2118,7 +2160,8 @@ type LexFilterImpl ( // The r.h.s. of an infix token begins a new block. | _, ctxts when (isInfix token && - not (isSameLine()) && + not (isSameLine()) && + canFollowInfixToken (peekNextToken()) && // This doesn't apply to the use of any infix tokens in a pattern match or 'when' block // For example // diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 111765fbbba..8acf62f42a1 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -3906,85 +3906,85 @@ declExpr: | declExpr INFIX_STAR_STAR_OP declExpr { mkSynInfix (rhs parseState 2) $1 $2 $3 } - | declExpr JOIN_IN OBLOCKEND_COMING_SOON + | declExpr JOIN_IN ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("in")) exprFromParseError(mkSynInfix (rhs parseState 2) $1 "@in" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr BAR_BAR OBLOCKEND_COMING_SOON + | declExpr BAR_BAR ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("||")) exprFromParseError(mkSynInfix (rhs parseState 2) $1 "||" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr INFIX_BAR_OP OBLOCKEND_COMING_SOON + | declExpr INFIX_BAR_OP ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr OR OBLOCKEND_COMING_SOON + | declExpr OR ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("or")) exprFromParseError(mkSynInfix (rhs parseState 2) $1 "or" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr AMP OBLOCKEND_COMING_SOON + | declExpr AMP ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("&")) exprFromParseError(mkSynInfix (rhs parseState 2) $1 "&" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr AMP_AMP OBLOCKEND_COMING_SOON + | declExpr AMP_AMP ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("&&")) exprFromParseError(mkSynInfix (rhs parseState 2) $1 "&&" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr INFIX_AMP_OP OBLOCKEND_COMING_SOON + | declExpr INFIX_AMP_OP ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr EQUALS OBLOCKEND_COMING_SOON + | declExpr EQUALS ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("=")) exprFromParseError(mkSynInfix (rhs parseState 2) $1 "=" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr INFIX_COMPARE_OP OBLOCKEND_COMING_SOON + | declExpr INFIX_COMPARE_OP ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr DOLLAR OBLOCKEND_COMING_SOON + | declExpr DOLLAR ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("$")) exprFromParseError(mkSynInfix (rhs parseState 2) $1 "$" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr LESS OBLOCKEND_COMING_SOON + | declExpr LESS ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("<")) exprFromParseError(mkSynInfix (rhs parseState 2) $1 "<" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr GREATER OBLOCKEND_COMING_SOON + | declExpr GREATER ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression(">")) exprFromParseError(mkSynInfix (rhs parseState 2) $1 ">" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr INFIX_AT_HAT_OP OBLOCKEND_COMING_SOON + | declExpr INFIX_AT_HAT_OP ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr PERCENT_OP OBLOCKEND_COMING_SOON + | declExpr PERCENT_OP ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr COLON_COLON OBLOCKEND_COMING_SOON + | declExpr COLON_COLON ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("::")) let identExpr = mkSynOperator (rhs parseState 2) "::" let tupExpr = SynExpr.Tuple (false, [$1;(arbExpr("declExprInfix", (rhs parseState 3).StartRange))], [rhs parseState 2], unionRanges $1.Range (rhs parseState 3).StartRange) SynExpr.App (ExprAtomicFlag.NonAtomic, true, identExpr, tupExpr, unionRanges $1.Range (rhs parseState 3).StartRange) } - | declExpr PLUS_MINUS_OP OBLOCKEND_COMING_SOON + | declExpr PLUS_MINUS_OP ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr MINUS OBLOCKEND_COMING_SOON + | declExpr MINUS ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("-")) exprFromParseError(mkSynInfix (rhs parseState 2) $1 "-" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr STAR OBLOCKEND_COMING_SOON + | declExpr STAR ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("*")) exprFromParseError(mkSynInfix (rhs parseState 2) $1 "*" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr INFIX_STAR_DIV_MOD_OP OBLOCKEND_COMING_SOON + | declExpr INFIX_STAR_DIV_MOD_OP ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } - | declExpr INFIX_STAR_STAR_OP OBLOCKEND_COMING_SOON + | declExpr INFIX_STAR_STAR_OP ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } From 4bce6881419aebc75ff5165a51f33ffb2bddd6ba Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 7 Jul 2022 20:05:57 +0200 Subject: [PATCH 2/2] Tmp --- src/Compiler/SyntaxTree/LexFilter.fs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index 705a16c25a7..bf0f1d3be4b 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -187,7 +187,7 @@ let canFollowInfixToken token = | ABSTRACT | AND | AND_BANG _ - | AS + // | AS | DONE | DOWNTO | ELIF @@ -221,7 +221,8 @@ let canFollowInfixToken token = | WHEN | WITH - | LBRACK_LESS -> false + // | LBRACK_LESS + -> false | _ -> true /// Matches against a left-parenthesis-like token that is valid in expressions.