mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-08 22:13:29 +00:00
parser enhancement: allow keywords after dots
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user