parser enhancement: allow keywords after dots

This commit is contained in:
Andreas Rumpf 2017-07-11 00:54:47 +02:00
commit 76cf4f4c1b
2 changed files with 34 additions and 24 deletions

View file

@ -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