nimgrammar
nimony/src/nifler2/nimgrammar.nim
The grammar of Nim.
Transcribed from Nim's doc/grammar.txt, which is itself generated from the #| comments in compiler/parser.nim. See doc/internals/parser_generator.md for the notation.
Transcription rules followed here:
doc/grammar.txtis the source, and where it disagrees with what
parser.nim actually does, the transcription follows parser.nim and says so in a # GRAMMAR.TXT: note. Collecting those is one of the points of the exercise.
- Ordered choice (
/) does not exist in the notation. Every/in the
original is resolved into either disjoint alternatives (usually by an indentation class), a left-factored set of entries, or a declared predicate — and the ones that needed a predicate are marked # PRED.
OP0..OP10and the eleven precedence-level rules are gone;binary(...)
owns precedence, exactly as parser.nim does.
DEDis implicit inindented(...).
proc canIdentOrLiteral(p: Parser; mode: PrimaryMode): boolproc canPrimarySuffix(p: Parser; mode: PrimaryMode): boolproc canCommandSuffix(p: Parser; mode: PrimaryMode): boolproc canTypeKAuxOperand(p: Parser; mode: PrimaryMode): boolproc canCommandParam(p: Parser; mode: PrimaryMode): boolproc canPrimary(p: Parser; mode: PrimaryMode): boolproc canGenericParamName(p: Parser): boolproc canStmt(p: Parser): boolproc pModule(p: var Parser)proc pComma(p: var Parser)proc pSemicolon(p: var Parser)proc pColon(p: var Parser)proc pColcom(p: var Parser)proc pTrailComment(p: var Parser)proc pFlexComment(p: var Parser)proc pValidInd(p: var Parser)proc pOptSameInd(p: var Parser)proc pNotInd(p: var Parser)proc pOptInd(p: var Parser)proc pOptPar(p: var Parser)proc pOperator(p: var Parser)proc pPrefixOperator(p: var Parser)proc pOperatorB(p: var Parser)proc pPlainSymbol(p: var Parser)proc pAccentEnd(p: var Parser)proc pQuotedLiteral(p: var Parser)proc pQuotedPunct(p: var Parser)proc pSymbol(p: var Parser)proc pSymbolOrKeyword(p: var Parser)proc pLiteral(p: var Parser)proc pGeneralizedLit(p: var Parser)proc pExprColonEqExpr(p: var Parser)proc pExprEqExpr(p: var Parser)proc pExprList(p: var Parser)proc pExprColonEqExprList(p: var Parser; close: TokKind)proc pListEnd(p: var Parser; close: TokKind)proc pQualifiedIdent(p: var Parser)proc pSetOrTableConstr(p: var Parser)proc pCastExpr(p: var Parser)proc pParKeyw(p: var Parser)proc pSemiStmtItem(p: var Parser)proc pSemiStmtList(p: var Parser)proc pPar(p: var Parser)proc pTupleConstr(p: var Parser)proc pTupleEnd(p: var Parser)proc pArrayConstr(p: var Parser)proc pIdentOrLiteral(p: var Parser; mode: PrimaryMode)proc pPrimarySuffix(p: var Parser; anchor: Mark; mode: PrimaryMode)proc pCommandSuffix(p: var Parser; anchor: Mark; mode: PrimaryMode)proc pPragma(p: var Parser)proc pExportMarker(p: var Parser)proc pIdentVis(p: var Parser)proc pIdentVisDot(p: var Parser)proc pIdentWithPragma(p: var Parser)proc pIdentWithPragmaDot(p: var Parser)proc pParamColonEquals(p: var Parser)proc pDeclColonEquals(p: var Parser)proc pIdentColonEquals(p: var Parser)proc pDeclColonEqualsDot(p: var Parser)proc pTupleTypeBracket(p: var Parser)proc pTupleType(p: var Parser)proc pTupleDecl(p: var Parser)proc pParamList(p: var Parser)proc pDoBlock(p: var Parser; atBody: bool)proc pRoutineSig(p: var Parser)proc pRoutineExpr(p: var Parser; mode: PrimaryMode)proc pFuncType(p: var Parser)proc pRoutineType(p: var Parser)proc pRawTypeDesc(p: var Parser)proc pTypeDescKeyw(p: var Parser; mode: PrimaryMode)proc pTypeKAuxOperand(p: var Parser; mode: PrimaryMode)proc pTypeDescExpr(p: var Parser)proc pTypeDesc(p: var Parser)proc pForVar(p: var Parser)proc pForTupleVar(p: var Parser)proc pForTuple(p: var Parser)proc pForHead(p: var Parser)proc pForStmt(p: var Parser)proc pForExpr(p: var Parser)proc pExpr(p: var Parser)proc pSimplePrimary(p: var Parser; mode: PrimaryMode)proc pCommandParam(p: var Parser; mode: PrimaryMode)proc pPrimary(p: var Parser; mode: PrimaryMode)proc pSimpleExpr(p: var Parser; limit: int64; mode: PrimaryMode)proc pPrimaryPragma(p: var Parser; mode: PrimaryMode)proc pExtraPostExprBlock(p: var Parser)proc pPostExprBlocks(p: var Parser)proc pExprBlocks(p: var Parser)proc pExprStmt(p: var Parser)proc pImportStmt(p: var Parser)proc pExportStmt(p: var Parser)proc pIncludeStmt(p: var Parser)proc pFromStmt(p: var Parser)proc pOptExprBody(p: var Parser)proc pReturnStmt(p: var Parser)proc pRaiseStmt(p: var Parser)proc pYieldStmt(p: var Parser)proc pDiscardStmt(p: var Parser)proc pBreakStmt(p: var Parser)proc pContinueStmt(p: var Parser)proc pCondStmt(p: var Parser)proc pIfStmt(p: var Parser)proc pWhenStmt(p: var Parser)proc pCondExpr(p: var Parser)proc pIfExpr(p: var Parser)proc pWhenExpr(p: var Parser)proc pWhileStmt(p: var Parser)proc pOfBranch(p: var Parser)proc pOfBranches(p: var Parser)proc pCaseStmt(p: var Parser)proc pTryStmt(p: var Parser)proc pTryBranches(p: var Parser)proc pTryExpr(p: var Parser)proc pTryExprBranches(p: var Parser)proc pBlockStmt(p: var Parser)proc pBlockExpr(p: var Parser)proc pNoIndHere(p: var Parser)proc pBlockNameEnd(p: var Parser)proc pStaticStmt(p: var Parser)proc pDeferStmt(p: var Parser)proc pAsmStmt(p: var Parser)proc pGenericParamName(p: var Parser)proc pGenericParam(p: var Parser)proc pGenericParamList(p: var Parser)proc pPattern(p: var Parser)proc pIndAndComment(p: var Parser)proc pRoutineName(p: var Parser)proc pRoutine(p: var Parser; kw: NiflerKind)proc pMissingEquals(p: var Parser)proc pCommentStmt(p: var Parser)proc pEnumDecl(p: var Parser)proc pObjectWhen(p: var Parser)proc pObjectElse(p: var Parser)proc pObjectBranch(p: var Parser)proc pBranchPart(p: var Parser)proc pObjectBranches(p: var Parser)proc pObjectCase(p: var Parser)proc pObjectPart(p: var Parser)proc pObjectDecl(p: var Parser)proc pObjectBody(p: var Parser)proc pEmptyDiscriminator(p: var Parser)proc pPosMarker(p: var Parser)proc pStrictListEnd(p: var Parser)proc pStrictListStart(p: var Parser)proc pEnumListEnd(p: var Parser)proc pParamStart(p: var Parser)proc pOfInherit(p: var Parser)proc pConceptParam(p: var Parser)proc pConceptDecl(p: var Parser)proc pTypeDef(p: var Parser)proc pTypeDefValue(p: var Parser)proc pTypeDefExpr(p: var Parser)proc pTupleVar(p: var Parser)proc pVarTupleLhs(p: var Parser)proc pNestedTuple(p: var Parser)proc pVarTupleBody(p: var Parser)proc pVarTuple(p: var Parser)proc pVariable(p: var Parser)proc pConstDef(p: var Parser)proc pConstant(p: var Parser)proc pBindStmt(p: var Parser)proc pMixinStmt(p: var Parser)proc pPragmaStmt(p: var Parser)proc pSimpleStmt(p: var Parser)proc pExprStart(p: var Parser)proc pComplexOrSimpleStmt(p: var Parser)proc pStmt(p: var Parser)proc pStmtListEnd(p: var Parser)proc pOneLinerStart(p: var Parser)proc pSection_typeDef(p: var Parser)proc pSection_constant(p: var Parser)proc pSection_variable(p: var Parser)proc parseModule(p: var Parser)A whole module, with
parser.nim'sparseTopLevelStmtchecks aroundmodule. An error is recorded inp, not reported.proc parseSnippet(code: string; asExpr: bool; pool: ref Pool.Obj; tags: ref TagPool.Obj; err: var string): TokenBufNim's
parseStmt(asExpr = false) andparseExpr:(stmts ...), or the one expression, intopoolandtags.erris the first error -- the lexer's messages come first, as nifler prints them -- and the result is empty when there is one.parseExprisparseStmtthat insists on exactly one statement, as it is in Nim's VM.