mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-07 21:43:33 +00:00
* fix issue #20922 by handling missing expr in `exprList` for `tkOf` * fix line numbers in test case * rewrite exprList requiring expr, add optionalExprList for except As suggested by @metagn. * update test case to reflect new code * update grammar.txt * update line numbers in test case taking into account nimout Given the number of errors that are produced it seems easier to do it this way instead of using `tt.Error`.
This commit is contained in:
@@ -451,6 +451,24 @@ proc exprList(p: var Parser, endTok: TokType, result: PNode) =
|
||||
getTok(p)
|
||||
optInd(p, result)
|
||||
# progress guaranteed
|
||||
var a = parseExpr(p)
|
||||
result.add(a)
|
||||
while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof):
|
||||
if p.tok.tokType != tkComma: break
|
||||
getTok(p)
|
||||
optInd(p, a)
|
||||
var a = parseExpr(p)
|
||||
result.add(a)
|
||||
when defined(nimpretty):
|
||||
dec p.em.doIndentMore
|
||||
|
||||
proc optionalExprList(p: var Parser, endTok: TokType, result: PNode) =
|
||||
#| optionalExprList = expr ^* comma
|
||||
when defined(nimpretty):
|
||||
inc p.em.doIndentMore
|
||||
getTok(p)
|
||||
optInd(p, result)
|
||||
# progress guaranteed
|
||||
while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof):
|
||||
var a = parseExpr(p)
|
||||
result.add(a)
|
||||
@@ -1436,7 +1454,7 @@ proc postExprBlocks(p: var Parser, x: PNode): PNode =
|
||||
#| postExprBlocks = ':' stmt? ( IND{=} doBlock
|
||||
#| | IND{=} 'of' exprList ':' stmt
|
||||
#| | IND{=} 'elif' expr ':' stmt
|
||||
#| | IND{=} 'except' exprList ':' stmt
|
||||
#| | IND{=} 'except' optionalExprList ':' stmt
|
||||
#| | IND{=} 'finally' ':' stmt
|
||||
#| | IND{=} 'else' ':' stmt )*
|
||||
result = x
|
||||
@@ -1494,7 +1512,7 @@ proc postExprBlocks(p: var Parser, x: PNode): PNode =
|
||||
nextBlock.add parseExpr(p)
|
||||
of tkExcept:
|
||||
nextBlock = newNodeP(nkExceptBranch, p)
|
||||
exprList(p, tkColon, nextBlock)
|
||||
optionalExprList(p, tkColon, nextBlock)
|
||||
of tkFinally:
|
||||
nextBlock = newNodeP(nkFinally, p)
|
||||
getTok(p)
|
||||
@@ -1746,10 +1764,10 @@ proc parseCase(p: var Parser): PNode =
|
||||
|
||||
proc parseTry(p: var Parser; isExpr: bool): PNode =
|
||||
#| tryStmt = 'try' colcom stmt &(IND{=}? 'except'|'finally')
|
||||
#| (IND{=}? 'except' exprList colcom stmt)*
|
||||
#| (IND{=}? 'except' optionalExprList colcom stmt)*
|
||||
#| (IND{=}? 'finally' colcom stmt)?
|
||||
#| tryExpr = 'try' colcom stmt &(optInd 'except'|'finally')
|
||||
#| (optInd 'except' exprList colcom stmt)*
|
||||
#| (optInd 'except' optionalExprList colcom stmt)*
|
||||
#| (optInd 'finally' colcom stmt)?
|
||||
result = newNodeP(nkTryStmt, p)
|
||||
getTok(p)
|
||||
@@ -1760,7 +1778,7 @@ proc parseTry(p: var Parser; isExpr: bool): PNode =
|
||||
case p.tok.tokType
|
||||
of tkExcept:
|
||||
b = newNodeP(nkExceptBranch, p)
|
||||
exprList(p, tkColon, b)
|
||||
optionalExprList(p, tkColon, b)
|
||||
of tkFinally:
|
||||
b = newNodeP(nkFinally, p)
|
||||
getTok(p)
|
||||
|
||||
@@ -30,6 +30,7 @@ symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
|
||||
exprColonEqExpr = expr (':'|'=' expr)?
|
||||
exprEqExpr = expr ('=' expr)?
|
||||
exprList = expr ^+ comma
|
||||
optionalExprList = expr ^* comma
|
||||
exprColonEqExprList = exprColonEqExpr (comma exprColonEqExpr)* (comma)?
|
||||
qualifiedIdent = symbol ('.' optInd symbol)?
|
||||
setOrTableConstr = '{' ((exprColonEqExpr comma)* | ':' ) '}'
|
||||
@@ -109,7 +110,7 @@ typeDefValue = ((tupleDecl | enumDecl | objectDecl | conceptDecl |
|
||||
postExprBlocks = ':' stmt? ( IND{=} doBlock
|
||||
| IND{=} 'of' exprList ':' stmt
|
||||
| IND{=} 'elif' expr ':' stmt
|
||||
| IND{=} 'except' exprList ':' stmt
|
||||
| IND{=} 'except' optionalExprList ':' stmt
|
||||
| IND{=} 'finally' ':' stmt
|
||||
| IND{=} 'else' ':' stmt )*
|
||||
exprStmt = simpleExpr postExprBlocks?
|
||||
@@ -148,10 +149,10 @@ caseStmt = 'case' expr ':'? COMMENT?
|
||||
(IND{>} ofBranches DED
|
||||
| IND{=} ofBranches)
|
||||
tryStmt = 'try' colcom stmt &(IND{=}? 'except'|'finally')
|
||||
(IND{=}? 'except' exprList colcom stmt)*
|
||||
(IND{=}? 'except' optionalExprList colcom stmt)*
|
||||
(IND{=}? 'finally' colcom stmt)?
|
||||
tryExpr = 'try' colcom stmt &(optInd 'except'|'finally')
|
||||
(optInd 'except' exprList colcom stmt)*
|
||||
(optInd 'except' optionalExprList colcom stmt)*
|
||||
(optInd 'finally' colcom stmt)?
|
||||
blockStmt = 'block' symbol? colcom stmt
|
||||
blockExpr = 'block' symbol? colcom stmt
|
||||
|
||||
46
tests/parser/t20922.nim
Normal file
46
tests/parser/t20922.nim
Normal file
@@ -0,0 +1,46 @@
|
||||
discard """
|
||||
cmd: "nim check $options --verbosity:0 $file"
|
||||
action: "reject"
|
||||
nimout: '''
|
||||
t20922.nim(37, 5) Error: expression expected, but found ':'
|
||||
Error: in expression ' '+'': identifier expected, but found ''
|
||||
t20922.nim(37, 7) Error: attempting to call undeclared routine: '<Error>'
|
||||
Error: in expression ' '+'': identifier expected, but found ''
|
||||
t20922.nim(37, 7) Error: attempting to call undeclared routine: '<Error>'
|
||||
t20922.nim(37, 7) Error: expression '' cannot be called
|
||||
t20922.nim(37, 7) Error: expression '' has no type (or is ambiguous)
|
||||
t20922.nim(37, 7) Error: VM problem: dest register is not set
|
||||
t20922.nim(45, 7) Error: expression expected, but found ':'
|
||||
t20922.nim(46, 5) Error: ':' or '=' expected, but got 'keyword of'
|
||||
t20922.nim(45, 9) Error: undeclared identifier: 'x'
|
||||
t20922.nim(45, 9) Error: expression 'x' has no type (or is ambiguous)
|
||||
Error: in expression ' x': identifier expected, but found ''
|
||||
t20922.nim(45, 9) Error: attempting to call undeclared routine: '<Error>'
|
||||
Error: in expression ' x': identifier expected, but found ''
|
||||
t20922.nim(45, 9) Error: attempting to call undeclared routine: '<Error>'
|
||||
t20922.nim(45, 9) Error: expression '' cannot be called
|
||||
t20922.nim(45, 9) Error: expression '' has no type (or is ambiguous)
|
||||
t20922.nim(45, 9) Error: VM problem: dest register is not set
|
||||
t20922.nim(33, 6) Hint: 'mapInstrToToken' is declared but not used [XDeclaredButNotUsed]
|
||||
t20922.nim(43, 3) Hint: 'Foo' is declared but not used [XDeclaredButNotUsed]
|
||||
'''
|
||||
"""
|
||||
# original test case issue #20922
|
||||
type Token = enum
|
||||
incDataPtr,
|
||||
incDataPtrByte
|
||||
|
||||
proc mapInstrToToken(instr: char): Token =
|
||||
case instr:
|
||||
of '>':
|
||||
incDataPtr
|
||||
of: '+':
|
||||
incDataPtrByte
|
||||
|
||||
# same issue with `of` in object branches (different parser procs calling `exprList`)
|
||||
type
|
||||
Bar = enum A, B
|
||||
Foo = object
|
||||
case kind: Bar
|
||||
of: x: int
|
||||
of B: y: float
|
||||
Reference in New Issue
Block a user