summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/parser.nim41
-rwxr-xr-xdoc/grammar.txt19
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'