Declarations are not parsed as expressions any more (JET-1)

This commit is contained in:
Andrey Breslav
2011-04-25 20:32:12 +04:00
parent 9059dae673
commit d4551a61bf
7 changed files with 104 additions and 33 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ initializer
; ;
block block
: "{" expressions "}" : "{" statements "}"
; ;
function function
+11 -6
View File
@@ -89,7 +89,7 @@ atomicExpression
: "typeof" "(" expression ")" : "typeof" "(" expression ")"
: "new" constructorInvocation : "new" constructorInvocation
: objectLiteral : objectLiteral
: declaration // : declaration
: jump : jump
: loop : loop
: SimpleName : SimpleName
@@ -126,6 +126,11 @@ declaration
: typedef : typedef
; ;
statement
: declaration
: expression
;
multiplicativeOperation multiplicativeOperation
: "*" : "/" : "%" : "*" : "/" : "%"
; ;
@@ -215,13 +220,13 @@ tupleLiteral // Ambiguity when after a SimpleName (infix call). In this case (e)
; ;
functionLiteral // one can use "it" as a parameter name functionLiteral // one can use "it" as a parameter name
: "{" expressions "}" : "{" statements "}"
: "{" (type ".")? modifiers SimpleName "=>" expressions "}" : "{" (type ".")? modifiers SimpleName "=>" statements "}"
: "{" (type ".")? "(" (modifiers SimpleName (":" type)?){","} ")" (":" type)? "=>" expressions "}" : "{" (type ".")? "(" (modifiers SimpleName (":" type)?){","} ")" (":" type)? "=>" statements "}"
; ;
expressions statements
: SEMI* expression{SEMI+} SEMI* : SEMI* statement{SEMI+} SEMI*
; ;
constructorInvocation constructorInvocation
@@ -172,11 +172,13 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
myBuilder.remapCurrentToken(keywordToken); myBuilder.remapCurrentToken(keywordToken);
return true; return true;
} }
} else { }
else {
// We know at this point that <code>set</code> does not contain <code>token</code> // We know at this point that <code>set</code> does not contain <code>token</code>
if (set.contains(IDENTIFIER) && token instanceof JetKeywordToken) { if (set.contains(IDENTIFIER) && token instanceof JetKeywordToken) {
if (((JetKeywordToken) token).isSoft()) { if (((JetKeywordToken) token).isSoft()) {
myBuilder.remapCurrentToken(IDENTIFIER); myBuilder.remapCurrentToken(IDENTIFIER);
return true;
} }
} }
} }
@@ -31,7 +31,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
COLON COLON
); );
/*package*/ static final TokenSet EXPRESSION_FIRST = TokenSet.orSet(TokenSet.create( /*package*/ static final TokenSet EXPRESSION_FIRST = TokenSet.create(
// Prefix // Prefix
MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL, LBRACKET, LABEL_IDENTIFIER, AT, ATAT, MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL, LBRACKET, LABEL_IDENTIFIER, AT, ATAT,
// Atomic // Atomic
@@ -57,14 +57,6 @@ public class JetExpressionParsing extends AbstractJetParsing {
NEW_KEYWORD, // new NEW_KEYWORD, // new
OBJECT_KEYWORD, // object OBJECT_KEYWORD, // object
// declaration
LBRACKET, // attribute
FUN_KEYWORD,
VAL_KEYWORD, VAR_KEYWORD,
EXTENSION_KEYWORD,
CLASS_KEYWORD,
TYPE_KEYWORD,
// jump // jump
THROW_KEYWORD, THROW_KEYWORD,
RETURN_KEYWORD, RETURN_KEYWORD,
@@ -80,7 +72,21 @@ public class JetExpressionParsing extends AbstractJetParsing {
FIELD_IDENTIFIER, // Field reference FIELD_IDENTIFIER, // Field reference
NAMESPACE_KEYWORD // for absolute qualified names NAMESPACE_KEYWORD // for absolute qualified names
), MODIFIER_KEYWORDS); );
private static final TokenSet STATEMENT_FIRST = TokenSet.orSet(
EXPRESSION_FIRST,
TokenSet.create(
// declaration
LBRACKET, // attribute
FUN_KEYWORD,
VAL_KEYWORD, VAR_KEYWORD,
EXTENSION_KEYWORD,
CLASS_KEYWORD,
TYPE_KEYWORD
),
MODIFIER_KEYWORDS
);
/*package*/ static final TokenSet EXPRESSION_FOLLOW = TokenSet.create( /*package*/ static final TokenSet EXPRESSION_FOLLOW = TokenSet.create(
SEMICOLON, DOUBLE_ARROW, COMMA, RBRACE, RPAR, RBRACKET SEMICOLON, DOUBLE_ARROW, COMMA, RBRACE, RPAR, RBRACKET
@@ -523,13 +529,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
parseSimpleNameExpression(); parseSimpleNameExpression();
} }
else if (at(IDENTIFIER)) { else if (at(IDENTIFIER)) {
if (JetParsing.MODIFIER_KEYWORD_MAP.containsKey(myBuilder.getTokenText())) { parseSimpleNameExpression();
if (!parseLocalDeclaration()) {
parseSimpleNameExpression();
}
} else {
parseSimpleNameExpression();
}
} }
else if (at(LBRACE)) { else if (at(LBRACE)) {
parseFunctionLiteral(); parseFunctionLiteral();
@@ -1022,7 +1022,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
} }
PsiBuilder.Marker body = mark(); PsiBuilder.Marker body = mark();
parseExpressions(); parseStatements();
body.done(BODY); body.done(BODY);
expect(RBRACE, "Expecting '}'"); expect(RBRACE, "Expecting '}'");
@@ -1073,27 +1073,39 @@ public class JetExpressionParsing extends AbstractJetParsing {
/* /*
* expressions * expressions
* : SEMI* element{SEMI+} SEMI* * : SEMI* statement{SEMI+} SEMI*
*/ */
public void parseExpressions() { public void parseStatements() {
while (at(SEMICOLON)) advance(); // SEMICOLON while (at(SEMICOLON)) advance(); // SEMICOLON
while (!eof() && !at(RBRACE)) { while (!eof() && !at(RBRACE)) {
if (!atSet(EXPRESSION_FIRST)) { if (!atSet(STATEMENT_FIRST)) {
errorAndAdvance("Expecting an element"); errorAndAdvance("Expecting an element");
} }
if (atSet(EXPRESSION_FIRST)) { if (atSet(STATEMENT_FIRST)) {
parseExpression(); parseStatement();
} }
if (at(SEMICOLON)) { if (at(SEMICOLON)) {
while (at(SEMICOLON)) advance(); // SEMICOLON while (at(SEMICOLON)) advance(); // SEMICOLON
} else if (at(RBRACE)) { } else if (at(RBRACE)) {
break; break;
} else if (!myBuilder.newlineBeforeCurrentToken()) { } else if (!myBuilder.newlineBeforeCurrentToken()) {
errorUntil("Unexpected tokens (use ';' to separate expressions on the same line", TokenSet.create(EOL_OR_SEMICOLON)); errorUntil("Unexpected tokens (use ';' to separate expressions on the same line)", TokenSet.create(EOL_OR_SEMICOLON));
} }
} }
} }
/*
* statement
* : expression
* : declaration
* ;
*/
private void parseStatement() {
if (!parseLocalDeclaration()) {
parseExpression();
}
}
/* /*
* declaration * declaration
* : function * : function
@@ -921,7 +921,7 @@ public class JetParsing extends AbstractJetParsing {
myBuilder.enableNewlines(); myBuilder.enableNewlines();
expect(LBRACE, "Expecting '{' to open a block"); expect(LBRACE, "Expecting '{' to open a block");
myExpressionParsing.parseExpressions(); myExpressionParsing.parseStatements();
expect(RBRACE, "Expecting '}"); expect(RBRACE, "Expecting '}");
myBuilder.restoreNewlinesState(); myBuilder.restoreNewlinesState();
+5
View File
@@ -0,0 +1,5 @@
// JET-1
val z = System.out
fun foo() { throw new Exception(); }
+47
View File
@@ -0,0 +1,47 @@
JetFile: ModifierAsSelector.jet
PsiComment(EOL_COMMENT)('// JET-1')
PsiWhiteSpace('\n\n')
NAMESPACE
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('z')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('System')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('out')
PsiWhiteSpace('\n\n')
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
TYPE_PARAMETER_LIST
<empty list>
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace(' ')
THROW
PsiElement(throw)('throw')
PsiWhiteSpace(' ')
NEW
PsiElement(new)('new')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Exception')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(SEMICOLON)(';')
PsiWhiteSpace(' ')
PsiElement(RBRACE)('}')