Recovery for expressions. Bug with return inside if fixed

This commit is contained in:
Andrey Breslav
2011-01-27 20:01:38 +03:00
parent 65cf049e73
commit 90eb9c443b
5 changed files with 133 additions and 6 deletions
+2
View File
@@ -76,6 +76,7 @@ postfixUnaryExpression
: memberAccess postfixUnaryOperation*
;
// !!! When you add here, remember to update the FIRST set in the parser
atomicExpression
: "(" expression ")" // see tupleLiteral
: literalConstant
@@ -92,6 +93,7 @@ atomicExpression
: jump
: loop
: SimpleName
: FieldName
: "namespace" // for the root namespace
;
@@ -29,6 +29,57 @@ public class JetExpressionParsing extends AbstractJetParsing {
COLON
);
private static final TokenSet EXPRESSION_FIRST = TokenSet.orSet(TokenSet.create(
// Prefix
MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL, LBRACKET,
// Atomic
LPAR, // parenthesized
// literal constant
TRUE_KEYWORD, FALSE_KEYWORD,
STRING_LITERAL, RAW_STRING_LITERAL,
INTEGER_LITERAL, LONG_LITERAL, CHARACTER_LITERAL, FLOAT_LITERAL,
NULL_KEYWORD,
LBRACE, // functionLiteral
LPAR, // tuple
THIS_KEYWORD, // this
IF_KEYWORD, // if
WHEN_KEYWORD, // when
TRY_KEYWORD, // try
TYPEOF_KEYWORD, // typeof
NEW_KEYWORD, // new
OBJECT_KEYWORD, // object
// declaration
LBRACKET, // attribute
FUN_KEYWORD,
VAL_KEYWORD, VAR_KEYWORD,
EXTENSION_KEYWORD,
CLASS_KEYWORD,
TYPE_KEYWORD,
// jump
THROW_KEYWORD,
RETURN_KEYWORD,
CONTINUE_KEYWORD,
BREAK_KEYWORD,
// loop
FOR_KEYWORD,
WHILE_KEYWORD,
DO_KEYWORD,
IDENTIFIER, // SimpleName
FIELD_IDENTIFIER, // Field reference
NAMESPACE_KEYWORD // for absolute qualified names
), MODIFIER_KEYWORDS);
private final JetParsing myJetParsing;
public JetExpressionParsing(SemanticWhitespaceAwarePsiBuilder builder, JetParsing jetParsing) {
@@ -141,8 +192,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
* ;
*/
public void parseExpression() {
// TODO: better recovery for expressions
if (atSet(RPAR, RBRACE, RBRACKET, GT)) {
if (!atSet(EXPRESSION_FIRST)) {
error("Expecting an expression");
return;
}
@@ -906,7 +956,12 @@ public class JetExpressionParsing extends AbstractJetParsing {
public void parseExpressions() {
while (at(SEMICOLON)) advance(); // SEMICOLON
while (!eof() && !at(RBRACE)) {
parseExpression();
if (!atSet(EXPRESSION_FIRST)) {
errorAndAdvance("Expecting an expression");
}
if (atSet(EXPRESSION_FIRST)) {
parseExpression();
}
if (at(SEMICOLON)) {
while (at(SEMICOLON)) advance(); // SEMICOLON
} else if (at(RBRACE)) {
@@ -993,6 +1048,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
* for
* : "for" "(" attributes valOrVar? SimpleName (":" type)? "in" expression ")" expression
* ;
*
* TODO: empty loop body (at the end of the block)?
*/
private void parseFor() {
assert _at(FOR_KEYWORD);
@@ -1162,7 +1219,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
advance(); // RETURN_KEYWORD
if (!at(EOL_OR_SEMICOLON)) parseExpression();
if (atSet(EXPRESSION_FIRST) && !at(EOL_OR_SEMICOLON)) parseExpression();
returnExpression.done(RETURN);
}
+9
View File
@@ -0,0 +1,9 @@
val f = if (true) return else {
dfsd
);;;);;;~;;;
srgsdfg
~
]
}
+58
View File
@@ -0,0 +1,58 @@
JetFile: Expressions_ERR.jet
NAMESPACE
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
IF
PsiElement(if)('if')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
CONDITION
BOOLEAN_CONSTANT
PsiElement(true)('true')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
THEN
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
PsiElement(else)('else')
PsiWhiteSpace(' ')
ELSE
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
BODY
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('dfsd')
PsiWhiteSpace('\n ')
PsiErrorElement:Expecting an expression
PsiElement(RPAR)(')')
PsiElement(SEMICOLON)(';')
PsiElement(SEMICOLON)(';')
PsiElement(SEMICOLON)(';')
PsiErrorElement:Expecting an expression
PsiElement(RPAR)(')')
PsiElement(SEMICOLON)(';')
PsiElement(SEMICOLON)(';')
PsiElement(SEMICOLON)(';')
PsiErrorElement:Expecting an expression
PsiElement(BAD_CHARACTER)('~')
PsiElement(SEMICOLON)(';')
PsiElement(SEMICOLON)(';')
PsiElement(SEMICOLON)(';')
PsiWhiteSpace('\n ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('srgsdfg')
PsiWhiteSpace('\n\n ')
PsiErrorElement:Expecting an expression
PsiElement(BAD_CHARACTER)('~')
PsiWhiteSpace('\n\n ')
PsiErrorElement:Expecting an expression
PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
+3 -2
View File
@@ -152,9 +152,10 @@ JetFile: When_ERR.jet
<empty list>
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting an expression
PsiElement(SEMICOLON)(';')
<empty list>
PsiWhiteSpace(' ')
PsiElement(SEMICOLON)(';')
PsiWhiteSpace('\n ')
WHEN_ENTRY
WHEN_CONDITION