diff options
-rw-r--r-- | compiler/parser.nim | 46 | ||||
-rw-r--r-- | doc/grammar.txt | 12 |
2 files changed, 34 insertions, 24 deletions
diff --git a/compiler/parser.nim b/compiler/parser.nim index 8bd99acd3..3cd1e4d92 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -39,6 +39,9 @@ type inPragma*: int # Pragma level inSemiStmtList*: int + SymbolMode = enum + smNormal, smAllowNil, smAfterDot + proc parseAll*(p: var TParser): PNode proc closeParser*(p: var TParser) proc parseTopLevelStmt*(p: var TParser): PNode @@ -62,7 +65,7 @@ proc optPar*(p: var TParser) proc optInd*(p: var TParser, n: PNode) proc indAndComment*(p: var TParser, n: PNode) proc setBaseFlags*(n: PNode, base: TNumericalBase) -proc parseSymbol*(p: var TParser, allowNil = false): PNode +proc parseSymbol*(p: var TParser, mode = smNormal): PNode proc parseTry(p: var TParser; isExpr: bool): PNode proc parseCase(p: var TParser): PNode proc parseStmtPragma(p: var TParser): PNode @@ -304,13 +307,24 @@ proc colcom(p: var TParser, n: PNode) = eat(p, tkColon) skipComment(p, n) -proc parseSymbol(p: var TParser, allowNil = false): PNode = +proc parseSymbol(p: var TParser, mode = smNormal): PNode = #| symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`' - #| | IDENT | 'addr' | 'type' + #| | IDENT | KEYW case p.tok.tokType - of tkSymbol, tkAddr, tkType: + of tkSymbol: result = newIdentNodeP(p.tok.ident, p) getTok(p) + of tokKeywordLow..tokKeywordHigh: + if p.tok.tokType == tkAddr or p.tok.tokType == tkType or mode == smAfterDot: + # for backwards compatibility these 2 are always valid: + result = newIdentNodeP(p.tok.ident, p) + getTok(p) + elif p.tok.tokType == tkNil and mode == smAllowNil: + result = newNodeP(nkNilLit, p) + getTok(p) + else: + parMessage(p, errIdentifierExpected, p.tok) + result = ast.emptyNode of tkAccent: result = newNodeP(nkAccQuoted, p) getTok(p) @@ -336,16 +350,12 @@ proc parseSymbol(p: var TParser, allowNil = false): PNode = break eat(p, tkAccent) else: - if allowNil and p.tok.tokType == tkNil: - result = newNodeP(nkNilLit, p) - getTok(p) - else: - parMessage(p, errIdentifierExpected, p.tok) - # BUGFIX: We must consume a token here to prevent endless loops! - # But: this really sucks for idetools and keywords, so we don't do it - # if it is a keyword: - #if not isKeyword(p.tok.tokType): getTok(p) - result = ast.emptyNode + parMessage(p, errIdentifierExpected, p.tok) + # BUGFIX: We must consume a token here to prevent endless loops! + # But: this really sucks for idetools and keywords, so we don't do it + # if it is a keyword: + #if not isKeyword(p.tok.tokType): getTok(p) + result = ast.emptyNode proc colonOrEquals(p: var TParser, a: PNode): PNode = if p.tok.tokType == tkColon: @@ -390,7 +400,7 @@ proc dotExpr(p: var TParser, a: PNode): PNode = result = newNodeI(nkDotExpr, info) optInd(p, result) addSon(result, a) - addSon(result, parseSymbol(p)) + addSon(result, parseSymbol(p, smAfterDot)) proc qualifiedIdent(p: var TParser): PNode = #| qualifiedIdent = symbol ('.' optInd symbol)? @@ -1005,10 +1015,10 @@ proc isExprStart(p: TParser): bool = result = true else: result = false -proc parseSymbolList(p: var TParser, result: PNode, allowNil = false) = +proc parseSymbolList(p: var TParser, result: PNode) = # progress guaranteed while true: - var s = parseSymbol(p, allowNil) + var s = parseSymbol(p, smAllowNil) if s.kind == nkEmpty: break addSon(result, s) if p.tok.tokType != tkComma: break @@ -1029,7 +1039,7 @@ proc parseTypeDescKAux(p: var TParser, kind: TNodeKind, getTok(p) let list = newNodeP(nodeKind, p) result.addSon list - parseSymbolList(p, list, allowNil = true) + parseSymbolList(p, list) proc parseExpr(p: var TParser): PNode = #| expr = (ifExpr diff --git a/doc/grammar.txt b/doc/grammar.txt index f50045233..58b119331 100644 --- a/doc/grammar.txt +++ b/doc/grammar.txt @@ -22,7 +22,7 @@ plusExpr = mulExpr (OP8 optInd mulExpr)* mulExpr = dollarExpr (OP9 optInd dollarExpr)* dollarExpr = primary (OP10 optInd primary)* symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`' - | IDENT | 'addr' | 'type' + | IDENT | KEYW exprColonEqExpr = expr (':'|'=' expr)? exprList = expr ^+ comma dotExpr = expr '.' optInd symbol @@ -81,7 +81,6 @@ paramList = '(' declColonEquals ^* (comma/semicolon) ')' paramListArrow = paramList? ('->' optInd typeDesc)? paramListColon = paramList? (':' optInd typeDesc)? doBlock = 'do' paramListArrow pragmas? colcom stmt -doBlocks = doBlock ^* IND{=} procExpr = 'proc' paramListColon pragmas? ('=' COMMENT? stmt)? distinct = 'distinct' optInd typeDesc expr = (ifExpr @@ -98,10 +97,11 @@ primary = typeKeyw typeDescK typeDesc = simpleExpr typeDefAux = simpleExpr | 'concept' typeClass -macroColon = ':' stmt? ( IND{=} 'of' exprList ':' stmt - | IND{=} 'elif' expr ':' stmt - | IND{=} 'except' exprList ':' stmt - | IND{=} 'else' ':' stmt )* +postExprBlocks = ':' stmt? ( IND{=} doBlock + | IND{=} 'of' exprList ':' stmt + | IND{=} 'elif' expr ':' stmt + | IND{=} 'except' exprList ':' stmt + | IND{=} 'else' ':' stmt )* exprStmt = simpleExpr (( '=' optInd expr colonBody? ) / ( expr ^+ comma |