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
: "{" expressions "}"
: "{" statements "}"
;
function
+11 -6
View File
@@ -89,7 +89,7 @@ atomicExpression
: "typeof" "(" expression ")"
: "new" constructorInvocation
: objectLiteral
: declaration
// : declaration
: jump
: loop
: SimpleName
@@ -126,6 +126,11 @@ declaration
: typedef
;
statement
: declaration
: expression
;
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
: "{" expressions "}"
: "{" (type ".")? modifiers SimpleName "=>" expressions "}"
: "{" (type ".")? "(" (modifiers SimpleName (":" type)?){","} ")" (":" type)? "=>" expressions "}"
: "{" statements "}"
: "{" (type ".")? modifiers SimpleName "=>" statements "}"
: "{" (type ".")? "(" (modifiers SimpleName (":" type)?){","} ")" (":" type)? "=>" statements "}"
;
expressions
: SEMI* expression{SEMI+} SEMI*
statements
: SEMI* statement{SEMI+} SEMI*
;
constructorInvocation
@@ -172,11 +172,13 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
myBuilder.remapCurrentToken(keywordToken);
return true;
}
} else {
}
else {
// We know at this point that <code>set</code> does not contain <code>token</code>
if (set.contains(IDENTIFIER) && token instanceof JetKeywordToken) {
if (((JetKeywordToken) token).isSoft()) {
myBuilder.remapCurrentToken(IDENTIFIER);
return true;
}
}
}
@@ -31,7 +31,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
COLON
);
/*package*/ static final TokenSet EXPRESSION_FIRST = TokenSet.orSet(TokenSet.create(
/*package*/ static final TokenSet EXPRESSION_FIRST = TokenSet.create(
// Prefix
MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL, LBRACKET, LABEL_IDENTIFIER, AT, ATAT,
// Atomic
@@ -57,14 +57,6 @@ public class JetExpressionParsing extends AbstractJetParsing {
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,
@@ -80,7 +72,21 @@ public class JetExpressionParsing extends AbstractJetParsing {
FIELD_IDENTIFIER, // Field reference
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(
SEMICOLON, DOUBLE_ARROW, COMMA, RBRACE, RPAR, RBRACKET
@@ -523,13 +529,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
parseSimpleNameExpression();
}
else if (at(IDENTIFIER)) {
if (JetParsing.MODIFIER_KEYWORD_MAP.containsKey(myBuilder.getTokenText())) {
if (!parseLocalDeclaration()) {
parseSimpleNameExpression();
}
} else {
parseSimpleNameExpression();
}
parseSimpleNameExpression();
}
else if (at(LBRACE)) {
parseFunctionLiteral();
@@ -1022,7 +1022,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
}
PsiBuilder.Marker body = mark();
parseExpressions();
parseStatements();
body.done(BODY);
expect(RBRACE, "Expecting '}'");
@@ -1073,27 +1073,39 @@ public class JetExpressionParsing extends AbstractJetParsing {
/*
* expressions
* : SEMI* element{SEMI+} SEMI*
* : SEMI* statement{SEMI+} SEMI*
*/
public void parseExpressions() {
public void parseStatements() {
while (at(SEMICOLON)) advance(); // SEMICOLON
while (!eof() && !at(RBRACE)) {
if (!atSet(EXPRESSION_FIRST)) {
if (!atSet(STATEMENT_FIRST)) {
errorAndAdvance("Expecting an element");
}
if (atSet(EXPRESSION_FIRST)) {
parseExpression();
if (atSet(STATEMENT_FIRST)) {
parseStatement();
}
if (at(SEMICOLON)) {
while (at(SEMICOLON)) advance(); // SEMICOLON
} else if (at(RBRACE)) {
break;
} 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
* : function
@@ -921,7 +921,7 @@ public class JetParsing extends AbstractJetParsing {
myBuilder.enableNewlines();
expect(LBRACE, "Expecting '{' to open a block");
myExpressionParsing.parseExpressions();
myExpressionParsing.parseStatements();
expect(RBRACE, "Expecting '}");
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)('}')