diff options
-rwxr-xr-x | compiler/parser.nim | 41 | ||||
-rwxr-xr-x | doc/grammar.txt | 19 |
2 files changed, 34 insertions, 26 deletions
diff --git a/compiler/parser.nim b/compiler/parser.nim index 871f486fc..c26b54531 100755 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -7,7 +7,7 @@ # distribution, for details about the copyright. # -# This module implements the parser of the standard Nimrod representation. +# This module implements the parser of the standard Nimrod syntax. # The parser strictly reflects the grammar ("doc/grammar.txt"); however # it uses several helper routines to keep the parser small. A special # efficient algorithm is used for the precedence levels. The parser here can @@ -259,13 +259,13 @@ proc dotdotExpr(p: var TParser, first: PNode): PNode = addSon(result, optExpr(p)) proc indexExpr(p: var TParser): PNode = - # indexExpr ::= '..' [expr] | expr ['=' expr | '..' expr] - if p.tok.tokType == tkDotDot: + # indexExpr ::= '..' [expr] | expr ['=' expr] + if p.tok.tokType == tkDotDot: result = dotdotExpr(p, ast.emptyNode) else: - var a = parseExpr(p) - case p.tok.tokType - of tkEquals: + result = parseExpr(p) + if p.tok.tokType == tkEquals: + var a = result result = newNodeP(nkExprEqExpr, p) addSon(result, a) getTok(p) @@ -275,9 +275,6 @@ proc indexExpr(p: var TParser): PNode = var b = parseExpr(p) if p.tok.tokType == tkDotDot: b = dotdotExpr(p, b) addSon(result, b) - of tkDotDot: - result = dotdotExpr(p, a) - else: result = a proc indexExprList(p: var TParser, first: PNode): PNode = result = newNodeP(nkBracketExpr, p) @@ -304,13 +301,13 @@ proc exprColonEqExpr(p: var TParser, kind: TNodeKind, tok: TTokType): PNode = addSon(result, parseExpr(p)) else: result = a - -proc exprListAux(p: var TParser, elemKind: TNodeKind, endTok, sepTok: TTokType, - result: PNode) = + +proc exprList(p: var TParser, endTok: TTokType, + result: PNode) = getTok(p) optInd(p, result) while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof): - var a = exprColonEqExpr(p, elemKind, sepTok) + var a = parseExpr(p) addSon(result, a) if p.tok.tokType != tkComma: break getTok(p) @@ -538,9 +535,19 @@ proc lowestExprAux(p: var TParser, v: var PNode, limit: int): PToken = opPrec = getPrecedence(nextop) result = op # return first untreated operator -proc lowestExpr(p: var TParser): PNode = +proc otherExpr(p: var TParser): PNode = discard lowestExprAux(p, result, - 1) +proc lowestExpr(p: var TParser): PNode = + result = otherExpr(p) + while p.tok.tokType == tkDotDot: + getTok(p) + optInd(p, result) + var a = result + result = newNodeP(nkRange, p) + addSon(result, a) + addSon(result, otherExpr(p)) + proc parseIfExpr(p: var TParser): PNode = result = newNodeP(nkIfExpr, p) while true: @@ -769,7 +776,7 @@ proc parseExprStmt(p: var TParser): PNode = case p.tok.tokType of tkOf: b = newNodeP(nkOfBranch, p) - exprListAux(p, nkRange, tkColon, tkDotDot, b) + exprList(p, tkColon, b) of tkElif: b = newNodeP(nkElifBranch, p) getTok(p) @@ -922,7 +929,7 @@ proc parseCase(p: var TParser): PNode = of tkOf: if inElif: break b = newNodeP(nkOfBranch, p) - exprListAux(p, nkRange, tkColon, tkDotDot, b) + exprList(p, tkColon, b) of tkElif: inElif = true b = newNodeP(nkElifBranch, p) @@ -1232,7 +1239,7 @@ proc parseObjectCase(p: var TParser): PNode = case p.tok.tokType of tkOf: b = newNodeP(nkOfBranch, p) - exprListAux(p, nkRange, tkColon, tkDotDot, b) + exprList(p, tkColon, b) of tkElse: b = newNodeP(nkElse, p) getTok(p) diff --git a/doc/grammar.txt b/doc/grammar.txt index 062698690..4ab5845a8 100755 --- a/doc/grammar.txt +++ b/doc/grammar.txt @@ -10,7 +10,8 @@ prefixOperator ::= OP0 | OP3 | OP4 | OP5 | OP6 | OP7 | 'not' optInd ::= [COMMENT] [IND] optPar ::= [IND] | [SAD] -lowestExpr ::= orExpr (OP0 optInd orExpr)* +lowestExpr ::= otherExpr ('..' optInd otherExpr)* +otherExpr ::= orExpr (OP0 optInd orExpr)* orExpr ::= andExpr (OR | 'xor' optInd andExpr)* andExpr ::= cmpExpr ('and' optInd cmpExpr)* cmpExpr ::= ampExpr (OP3 | 'is' | 'isnot' | 'in' | 'notin' optInd ampExpr)* @@ -19,7 +20,7 @@ plusExpr ::= mulExpr (OP5 optInd mulExpr)* mulExpr ::= dollarExpr (OP6 | 'div' | 'mod' | 'shl' | 'shr' optInd dollarExpr)* dollarExpr ::= primary (OP7 optInd primary)* -indexExpr ::= '..' [expr] | expr ['=' expr | '..' expr] +indexExpr ::= '..' [expr] | expr ['=' expr] castExpr ::= 'cast' '[' optInd typeDesc optPar ']' '(' optInd expr optPar ')' addrExpr ::= 'addr' '(' optInd expr optPar ')' @@ -49,7 +50,7 @@ literal ::= INT_LIT | INT8_LIT | INT16_LIT | INT32_LIT | INT64_LIT constructor ::= literal | '[' optInd colonExprList optPar ']' - | '{' optInd sliceExprList optPar '}' + | '{' optInd ':' | colonExprList optPar '}' | '(' optInd colonExprList optPar ')' colonExpr ::= expr [':' expr] @@ -58,9 +59,6 @@ colonExprList ::= [colonExpr (comma colonExpr)* [comma]] namedExpr ::= expr ['=' expr] namedExprList ::= [namedExpr (comma namedExpr)* [comma]] -sliceExpr ::= expr ['..' expr] -sliceExprList ::= [sliceExpr (comma sliceExpr)* [comma]] - exprOrType ::= lowestExpr | 'if' expr ':' expr ('elif' expr ':' expr)* 'else' ':' expr | 'var' exprOrType @@ -72,12 +70,15 @@ exprOrType ::= lowestExpr expr ::= exprOrType | 'proc' paramList [pragma] ['=' stmt] +exprList ::= [expr (comma expr)* [comma]] + + qualifiedIdent ::= symbol ['.' symbol] typeDesc ::= exprOrType | 'proc' paramList [pragma] -macroStmt ::= ':' [stmt] ('of' [sliceExprList] ':' stmt +macroStmt ::= ':' [stmt] ('of' [exprList] ':' stmt |'elif' expr ':' stmt |'except' exceptList ':' stmt )* ['else' ':' stmt] @@ -115,7 +116,7 @@ breakStmt ::= 'break' [symbol] continueStmt ::= 'continue' ifStmt ::= 'if' expr ':' stmt ('elif' expr ':' stmt)* ['else' ':' stmt] whenStmt ::= 'when' expr ':' stmt ('elif' expr ':' stmt)* ['else' ':' stmt] -caseStmt ::= 'case' expr [':'] ('of' sliceExprList ':' stmt)* +caseStmt ::= 'case' expr [':'] ('of' exprList ':' stmt)* ('elif' expr ':' stmt)* ['else' ':' stmt] whileStmt ::= 'while' expr ':' stmt @@ -167,7 +168,7 @@ objectWhen ::= 'when' expr ':' [COMMENT] objectPart ('elif' expr ':' [COMMENT] objectPart)* ['else' ':' [COMMENT] objectPart] objectCase ::= 'case' expr ':' typeDesc [COMMENT] - ('of' sliceExprList ':' [COMMENT] objectPart)* + ('of' exprList ':' [COMMENT] objectPart)* ['else' ':' [COMMENT] objectPart] objectPart ::= objectWhen | objectCase | objectIdentPart | 'nil' |