parser enhancement: allow keywords after dots
This commit is contained in:
parent
5932ad9ae8
commit
76cf4f4c1b
2 changed files with 34 additions and 24 deletions
|
|
@ -39,6 +39,9 @@ type
|
||||||
inPragma*: int # Pragma level
|
inPragma*: int # Pragma level
|
||||||
inSemiStmtList*: int
|
inSemiStmtList*: int
|
||||||
|
|
||||||
|
SymbolMode = enum
|
||||||
|
smNormal, smAllowNil, smAfterDot
|
||||||
|
|
||||||
proc parseAll*(p: var TParser): PNode
|
proc parseAll*(p: var TParser): PNode
|
||||||
proc closeParser*(p: var TParser)
|
proc closeParser*(p: var TParser)
|
||||||
proc parseTopLevelStmt*(p: var TParser): PNode
|
proc parseTopLevelStmt*(p: var TParser): PNode
|
||||||
|
|
@ -62,7 +65,7 @@ proc optPar*(p: var TParser)
|
||||||
proc optInd*(p: var TParser, n: PNode)
|
proc optInd*(p: var TParser, n: PNode)
|
||||||
proc indAndComment*(p: var TParser, n: PNode)
|
proc indAndComment*(p: var TParser, n: PNode)
|
||||||
proc setBaseFlags*(n: PNode, base: TNumericalBase)
|
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 parseTry(p: var TParser; isExpr: bool): PNode
|
||||||
proc parseCase(p: var TParser): PNode
|
proc parseCase(p: var TParser): PNode
|
||||||
proc parseStmtPragma(p: var TParser): PNode
|
proc parseStmtPragma(p: var TParser): PNode
|
||||||
|
|
@ -304,13 +307,24 @@ proc colcom(p: var TParser, n: PNode) =
|
||||||
eat(p, tkColon)
|
eat(p, tkColon)
|
||||||
skipComment(p, n)
|
skipComment(p, n)
|
||||||
|
|
||||||
proc parseSymbol(p: var TParser, allowNil = false): PNode =
|
proc parseSymbol(p: var TParser, mode = smNormal): PNode =
|
||||||
#| symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
|
#| symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
|
||||||
#| | IDENT | 'addr' | 'type'
|
#| | IDENT | KEYW
|
||||||
case p.tok.tokType
|
case p.tok.tokType
|
||||||
of tkSymbol, tkAddr, tkType:
|
of tkSymbol:
|
||||||
result = newIdentNodeP(p.tok.ident, p)
|
result = newIdentNodeP(p.tok.ident, p)
|
||||||
getTok(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:
|
of tkAccent:
|
||||||
result = newNodeP(nkAccQuoted, p)
|
result = newNodeP(nkAccQuoted, p)
|
||||||
getTok(p)
|
getTok(p)
|
||||||
|
|
@ -335,10 +349,6 @@ proc parseSymbol(p: var TParser, allowNil = false): PNode =
|
||||||
parMessage(p, errIdentifierExpected, p.tok)
|
parMessage(p, errIdentifierExpected, p.tok)
|
||||||
break
|
break
|
||||||
eat(p, tkAccent)
|
eat(p, tkAccent)
|
||||||
else:
|
|
||||||
if allowNil and p.tok.tokType == tkNil:
|
|
||||||
result = newNodeP(nkNilLit, p)
|
|
||||||
getTok(p)
|
|
||||||
else:
|
else:
|
||||||
parMessage(p, errIdentifierExpected, p.tok)
|
parMessage(p, errIdentifierExpected, p.tok)
|
||||||
# BUGFIX: We must consume a token here to prevent endless loops!
|
# BUGFIX: We must consume a token here to prevent endless loops!
|
||||||
|
|
@ -390,7 +400,7 @@ proc dotExpr(p: var TParser, a: PNode): PNode =
|
||||||
result = newNodeI(nkDotExpr, info)
|
result = newNodeI(nkDotExpr, info)
|
||||||
optInd(p, result)
|
optInd(p, result)
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
addSon(result, parseSymbol(p))
|
addSon(result, parseSymbol(p, smAfterDot))
|
||||||
|
|
||||||
proc qualifiedIdent(p: var TParser): PNode =
|
proc qualifiedIdent(p: var TParser): PNode =
|
||||||
#| qualifiedIdent = symbol ('.' optInd symbol)?
|
#| qualifiedIdent = symbol ('.' optInd symbol)?
|
||||||
|
|
@ -1005,10 +1015,10 @@ proc isExprStart(p: TParser): bool =
|
||||||
result = true
|
result = true
|
||||||
else: result = false
|
else: result = false
|
||||||
|
|
||||||
proc parseSymbolList(p: var TParser, result: PNode, allowNil = false) =
|
proc parseSymbolList(p: var TParser, result: PNode) =
|
||||||
# progress guaranteed
|
# progress guaranteed
|
||||||
while true:
|
while true:
|
||||||
var s = parseSymbol(p, allowNil)
|
var s = parseSymbol(p, smAllowNil)
|
||||||
if s.kind == nkEmpty: break
|
if s.kind == nkEmpty: break
|
||||||
addSon(result, s)
|
addSon(result, s)
|
||||||
if p.tok.tokType != tkComma: break
|
if p.tok.tokType != tkComma: break
|
||||||
|
|
@ -1029,7 +1039,7 @@ proc parseTypeDescKAux(p: var TParser, kind: TNodeKind,
|
||||||
getTok(p)
|
getTok(p)
|
||||||
let list = newNodeP(nodeKind, p)
|
let list = newNodeP(nodeKind, p)
|
||||||
result.addSon list
|
result.addSon list
|
||||||
parseSymbolList(p, list, allowNil = true)
|
parseSymbolList(p, list)
|
||||||
|
|
||||||
proc parseExpr(p: var TParser): PNode =
|
proc parseExpr(p: var TParser): PNode =
|
||||||
#| expr = (ifExpr
|
#| expr = (ifExpr
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ plusExpr = mulExpr (OP8 optInd mulExpr)*
|
||||||
mulExpr = dollarExpr (OP9 optInd dollarExpr)*
|
mulExpr = dollarExpr (OP9 optInd dollarExpr)*
|
||||||
dollarExpr = primary (OP10 optInd primary)*
|
dollarExpr = primary (OP10 optInd primary)*
|
||||||
symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
|
symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
|
||||||
| IDENT | 'addr' | 'type'
|
| IDENT | KEYW
|
||||||
exprColonEqExpr = expr (':'|'=' expr)?
|
exprColonEqExpr = expr (':'|'=' expr)?
|
||||||
exprList = expr ^+ comma
|
exprList = expr ^+ comma
|
||||||
dotExpr = expr '.' optInd symbol
|
dotExpr = expr '.' optInd symbol
|
||||||
|
|
@ -81,7 +81,6 @@ paramList = '(' declColonEquals ^* (comma/semicolon) ')'
|
||||||
paramListArrow = paramList? ('->' optInd typeDesc)?
|
paramListArrow = paramList? ('->' optInd typeDesc)?
|
||||||
paramListColon = paramList? (':' optInd typeDesc)?
|
paramListColon = paramList? (':' optInd typeDesc)?
|
||||||
doBlock = 'do' paramListArrow pragmas? colcom stmt
|
doBlock = 'do' paramListArrow pragmas? colcom stmt
|
||||||
doBlocks = doBlock ^* IND{=}
|
|
||||||
procExpr = 'proc' paramListColon pragmas? ('=' COMMENT? stmt)?
|
procExpr = 'proc' paramListColon pragmas? ('=' COMMENT? stmt)?
|
||||||
distinct = 'distinct' optInd typeDesc
|
distinct = 'distinct' optInd typeDesc
|
||||||
expr = (ifExpr
|
expr = (ifExpr
|
||||||
|
|
@ -98,7 +97,8 @@ primary = typeKeyw typeDescK
|
||||||
typeDesc = simpleExpr
|
typeDesc = simpleExpr
|
||||||
typeDefAux = simpleExpr
|
typeDefAux = simpleExpr
|
||||||
| 'concept' typeClass
|
| 'concept' typeClass
|
||||||
macroColon = ':' stmt? ( IND{=} 'of' exprList ':' stmt
|
postExprBlocks = ':' stmt? ( IND{=} doBlock
|
||||||
|
| IND{=} 'of' exprList ':' stmt
|
||||||
| IND{=} 'elif' expr ':' stmt
|
| IND{=} 'elif' expr ':' stmt
|
||||||
| IND{=} 'except' exprList ':' stmt
|
| IND{=} 'except' exprList ':' stmt
|
||||||
| IND{=} 'else' ':' stmt )*
|
| IND{=} 'else' ':' stmt )*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue