# GENERATED BY NifGram. DO NOT EDIT!
# ORIGINAL FILE: src/nifgram/examples/test_grammar.nif
proc matchExpr(c: var Context; it: var Item): bool
proc matchStmt(c: var Context; it: var Item): bool
proc matchType(c: var Context; it: var Item): bool
proc matchVarPragmas(c: var Context; it: var Item): bool
proc matchStmtList(c: var Context; it: var Item): bool
proc matchParamPragmas(c: var Context; it: var Item): bool
proc matchProcPragmas(c: var Context; it: var Item): bool
proc matchFieldPragmas(c: var Context; it: var Item): bool
proc matchProcTypePragmas(c: var Context; it: var Item): bool
proc matchTypePragmas(c: var Context; it: var Item): bool



proc matchIntBits(c: var Context; it: var Item): bool =
  when declared(handleIntBits):
    var before1 = save(c, it)
  if not matchIntLit(c, it): return false
  when declared(handleIntBits):
    handleIntBits(c, it, before1)
  return true

proc matchLvalue(c: var Context; it: var Item): bool =
  when declared(handleLvalue):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if lookupSym(c, it):
      or2 = true
      break or3
    var kw4 = false
    if isTag(c, it, DerefT):
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
    var kw5 = false
    if isTag(c, it, AtT):
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw5 = matchParRi(c, it)
    if kw5:
      or2 = true
      break or3
    var kw6 = false
    if isTag(c, it, DotT):
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not lookupSym(c, it):
        error(c, it, "SYMBOL expected")
      if not matchIntLit(c, it):
        error(c, it, "INTLIT expected")
      kw6 = matchParRi(c, it)
    if kw6:
      or2 = true
      break or3
    var kw7 = false
    if isTag(c, it, PatT):
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw7 = matchParRi(c, it)
    if kw7:
      or2 = true
      break or3
    if isTag(c, it, ErrvT):
      or2 = true
      break or3
    if isTag(c, it, OvffT):
      or2 = true
      break or3
  if not or2: return false
  when declared(handleLvalue):
    handleLvalue(c, it, before1)
  return true

proc matchCall(c: var Context; it: var Item): bool =
  when declared(handleCall):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, CallT):
    var om3 = false
    while not peekParRi(c, it):
      if not matchExpr(c, it):
        break
      else:
        om3 = true
    if not om3:
      error(c, it, "invalid Call")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleCall):
    handleCall(c, it, before1)
  return true

proc matchCallCanRaise(c: var Context; it: var Item): bool =
  when declared(handleCallCanRaise):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, OnerrT):
    if not matchStmt(c, it):
      error(c, it, "Stmt expected")
    var om3 = false
    while not peekParRi(c, it):
      if not matchExpr(c, it):
        break
      else:
        om3 = true
    if not om3:
      error(c, it, "invalid CallCanRaise")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleCallCanRaise):
    handleCallCanRaise(c, it, before1)
  return true

proc matchArithExpr(c: var Context; it: var Item): bool =
  when declared(handleArithExpr):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    var kw4 = false
    if isTag(c, it, AddT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
    var kw5 = false
    if isTag(c, it, SubT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw5 = matchParRi(c, it)
    if kw5:
      or2 = true
      break or3
    var kw6 = false
    if isTag(c, it, MulT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw6 = matchParRi(c, it)
    if kw6:
      or2 = true
      break or3
    var kw7 = false
    if isTag(c, it, DivT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw7 = matchParRi(c, it)
    if kw7:
      or2 = true
      break or3
    var kw8 = false
    if isTag(c, it, ModT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw8 = matchParRi(c, it)
    if kw8:
      or2 = true
      break or3
  if not or2: return false
  when declared(handleArithExpr):
    handleArithExpr(c, it, before1)
  return true

proc matchExpr(c: var Context; it: var Item): bool =
  when declared(handleExpr):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchIntLit(c, it):
      or2 = true
      break or3
    if matchUIntLit(c, it):
      or2 = true
      break or3
    if matchFloatLit(c, it):
      or2 = true
      break or3
    if matchCharLit(c, it):
      or2 = true
      break or3
    if matchStringLit(c, it):
      or2 = true
      break or3
    if matchLvalue(c, it):
      or2 = true
      break or3
    var kw4 = false
    if isTag(c, it, ParT):
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
    var kw5 = false
    if isTag(c, it, AddrT):
      if not matchLvalue(c, it):
        error(c, it, "Lvalue expected")
      kw5 = matchParRi(c, it)
    if kw5:
      or2 = true
      break or3
    if isTag(c, it, NilT):
      or2 = true
      break or3
    if isTag(c, it, FalseT):
      or2 = true
      break or3
    if isTag(c, it, TrueT):
      or2 = true
      break or3
    if isTag(c, it, InfT):
      or2 = true
      break or3
    if isTag(c, it, NeginfT):
      or2 = true
      break or3
    if isTag(c, it, NanT):
      or2 = true
      break or3
    var kw6 = false
    if isTag(c, it, AndT):
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw6 = matchParRi(c, it)
    if kw6:
      or2 = true
      break or3
    var kw7 = false
    if isTag(c, it, OrT):
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw7 = matchParRi(c, it)
    if kw7:
      or2 = true
      break or3
    var kw8 = false
    if isTag(c, it, NotT):
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw8 = matchParRi(c, it)
    if kw8:
      or2 = true
      break or3
    var kw9 = false
    if isTag(c, it, NegT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw9 = matchParRi(c, it)
    if kw9:
      or2 = true
      break or3
    var kw10 = false
    if isTag(c, it, SizeofT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      kw10 = matchParRi(c, it)
    if kw10:
      or2 = true
      break or3
    var kw11 = false
    if isTag(c, it, AlignofT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      kw11 = matchParRi(c, it)
    if kw11:
      or2 = true
      break or3
    var kw12 = false
    if isTag(c, it, OffsetofT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not lookupSym(c, it):
        error(c, it, "SYMBOL expected")
      kw12 = matchParRi(c, it)
    if kw12:
      or2 = true
      break or3
    var kw13 = false
    if isTag(c, it, OconstrT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      var zm14 = true
      while not peekParRi(c, it):
        var kw15 = false
        if isTag(c, it, KvT):
          if not lookupSym(c, it):
            error(c, it, "SYMBOL expected")
          if not matchExpr(c, it):
            error(c, it, "Expr expected")
          kw15 = matchParRi(c, it)
        if not kw15:
          zm14 = false
          break
      if not zm14:
        error(c, it, "invalid Expr")
      kw13 = matchParRi(c, it)
    if kw13:
      or2 = true
      break or3
    var kw16 = false
    if isTag(c, it, AconstrT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      var zm17 = true
      while not peekParRi(c, it):
        if not matchExpr(c, it):
          zm17 = false
          break
      if not zm17:
        error(c, it, "invalid Expr")
      kw16 = matchParRi(c, it)
    if kw16:
      or2 = true
      break or3
    if matchArithExpr(c, it):
      or2 = true
      break or3
    var kw18 = false
    if isTag(c, it, ShrT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw18 = matchParRi(c, it)
    if kw18:
      or2 = true
      break or3
    var kw19 = false
    if isTag(c, it, ShlT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw19 = matchParRi(c, it)
    if kw19:
      or2 = true
      break or3
    var kw20 = false
    if isTag(c, it, BitandT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw20 = matchParRi(c, it)
    if kw20:
      or2 = true
      break or3
    var kw21 = false
    if isTag(c, it, BitorT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw21 = matchParRi(c, it)
    if kw21:
      or2 = true
      break or3
    var kw22 = false
    if isTag(c, it, BitnotT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw22 = matchParRi(c, it)
    if kw22:
      or2 = true
      break or3
    var kw23 = false
    if isTag(c, it, BitxorT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw23 = matchParRi(c, it)
    if kw23:
      or2 = true
      break or3
    var kw24 = false
    if isTag(c, it, EqT):
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw24 = matchParRi(c, it)
    if kw24:
      or2 = true
      break or3
    var kw25 = false
    if isTag(c, it, NeqT):
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw25 = matchParRi(c, it)
    if kw25:
      or2 = true
      break or3
    var kw26 = false
    if isTag(c, it, LeT):
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw26 = matchParRi(c, it)
    if kw26:
      or2 = true
      break or3
    var kw27 = false
    if isTag(c, it, LtT):
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw27 = matchParRi(c, it)
    if kw27:
      or2 = true
      break or3
    var kw28 = false
    if isTag(c, it, CastT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw28 = matchParRi(c, it)
    if kw28:
      or2 = true
      break or3
    var kw29 = false
    if isTag(c, it, ConvT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      if not matchExpr(c, it):
        error(c, it, "Expr expected")
      kw29 = matchParRi(c, it)
    if kw29:
      or2 = true
      break or3
    if matchCall(c, it):
      or2 = true
      break or3
    if matchCallCanRaise(c, it):
      or2 = true
      break or3
  if not or2: return false
  when declared(handleExpr):
    handleExpr(c, it, before1)
  return true

proc matchBranchValue(c: var Context; it: var Item): bool =
  when declared(handleBranchValue):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchIntLit(c, it):
      or2 = true
      break or3
    if matchUIntLit(c, it):
      or2 = true
      break or3
    if matchCharLit(c, it):
      or2 = true
      break or3
    if lookupSym(c, it):
      or2 = true
      break or3
    if isTag(c, it, FalseT):
      or2 = true
      break or3
    if isTag(c, it, TrueT):
      or2 = true
      break or3
  if not or2: return false
  when declared(handleBranchValue):
    handleBranchValue(c, it, before1)
  return true

proc matchBranchRange(c: var Context; it: var Item): bool =
  when declared(handleBranchRange):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchBranchValue(c, it):
      or2 = true
      break or3
    var kw4 = false
    if isTag(c, it, RangeT):
      if not matchBranchValue(c, it):
        error(c, it, "BranchValue expected")
      if not matchBranchValue(c, it):
        error(c, it, "BranchValue expected")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
  if not or2: return false
  when declared(handleBranchRange):
    handleBranchRange(c, it, before1)
  return true

proc matchBranchRanges(c: var Context; it: var Item): bool =
  when declared(handleBranchRanges):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    var kw4 = false
    if isTag(c, it, RangesT):
      var om5 = false
      while not peekParRi(c, it):
        if not matchBranchRange(c, it):
          break
        else:
          om5 = true
      if not om5:
        error(c, it, "invalid BranchRanges")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
  if not or2: return false
  when declared(handleBranchRanges):
    handleBranchRanges(c, it, before1)
  return true

proc matchVarDeclCommon(c: var Context; it: var Item): bool =
  when declared(handleVarDeclCommon):
    var before1 = save(c, it)
  var sym2 = declareSym(c, it)
  if not success(sym2): return false
  if not matchVarPragmas(c, it): return false
  if not matchType(c, it): return false
  var or3 = false
  block or4:
    if matchEmpty(c, it):
      or3 = true
      break or4
    if matchExpr(c, it):
      or3 = true
      break or4
  if not or3: return false
  when declared(handleVarDeclCommon):
    handleVarDeclCommon(c, it, before1)
  return true

proc matchVarDecl(c: var Context; it: var Item): bool =
  when declared(handleVarDecl):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    var kw4 = false
    if isTag(c, it, VarT):
      if not matchVarDeclCommon(c, it):
        error(c, it, "VarDeclCommon expected")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
    var kw5 = false
    if isTag(c, it, GvarT):
      if not matchVarDeclCommon(c, it):
        error(c, it, "VarDeclCommon expected")
      kw5 = matchParRi(c, it)
    if kw5:
      or2 = true
      break or3
    var kw6 = false
    if isTag(c, it, TvarT):
      if not matchVarDeclCommon(c, it):
        error(c, it, "VarDeclCommon expected")
      kw6 = matchParRi(c, it)
    if kw6:
      or2 = true
      break or3
  if not or2: return false
  when declared(handleVarDecl):
    handleVarDecl(c, it, before1)
  return true

proc matchConstDecl(c: var Context; it: var Item): bool =
  when declared(handleConstDecl):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, ConstT):
    var sym3 = declareSym(c, it)
    if not success(sym3):
      error(c, it, "SYMBOLDEF expected")
    if not matchVarPragmas(c, it):
      error(c, it, "VarPragmas expected")
    if not matchType(c, it):
      error(c, it, "Type expected")
    if not matchExpr(c, it):
      error(c, it, "Expr expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleConstDecl):
    handleConstDecl(c, it, before1)
  return true

proc matchEmitStmt(c: var Context; it: var Item): bool =
  when declared(handleEmitStmt):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, EmitT):
    var om3 = false
    while not peekParRi(c, it):
      if not matchExpr(c, it):
        break
      else:
        om3 = true
    if not om3:
      error(c, it, "invalid EmitStmt")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleEmitStmt):
    handleEmitStmt(c, it, before1)
  return true

proc matchTryStmt(c: var Context; it: var Item): bool =
  when declared(handleTryStmt):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, TryT):
    if not matchStmtList(c, it):
      error(c, it, "StmtList expected")
    if not matchStmtList(c, it):
      error(c, it, "StmtList expected")
    if not matchStmtList(c, it):
      error(c, it, "StmtList expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleTryStmt):
    handleTryStmt(c, it, before1)
  return true

proc matchRaiseStmt(c: var Context; it: var Item): bool =
  when declared(handleRaiseStmt):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, RaiseT):
    var or3 = false
    block or4:
      if matchEmpty(c, it):
        or3 = true
        break or4
      if matchExpr(c, it):
        or3 = true
        break or4
    if not or3:
      error(c, it, "invalid RaiseStmt")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleRaiseStmt):
    handleRaiseStmt(c, it, before1)
  return true

proc matchAsgnStmt(c: var Context; it: var Item): bool =
  when declared(handleAsgnStmt):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, AsgnT):
    if not matchLvalue(c, it):
      error(c, it, "Lvalue expected")
    if not matchExpr(c, it):
      error(c, it, "Expr expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleAsgnStmt):
    handleAsgnStmt(c, it, before1)
  return true

proc matchKeepOverflowStmt(c: var Context; it: var Item): bool =
  when declared(handleKeepOverflowStmt):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, KeepovfT):
    if not matchArithExpr(c, it):
      error(c, it, "ArithExpr expected")
    if not matchLvalue(c, it):
      error(c, it, "Lvalue expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleKeepOverflowStmt):
    handleKeepOverflowStmt(c, it, before1)
  return true

proc matchIfStmt(c: var Context; it: var Item): bool =
  when declared(handleIfStmt):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, IfT):
    var om3 = false
    while not peekParRi(c, it):
      var kw4 = false
      if isTag(c, it, ElifT):
        if not matchExpr(c, it):
          error(c, it, "Expr expected")
        if not matchStmtList(c, it):
          error(c, it, "StmtList expected")
        kw4 = matchParRi(c, it)
      if not kw4:
        break
      else:
        om3 = true
    if not om3:
      error(c, it, "invalid IfStmt")
    var kw5 = false
    if isTag(c, it, ElseT):
      if not matchStmtList(c, it):
        error(c, it, "StmtList expected")
      kw5 = matchParRi(c, it)
    discard kw5
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleIfStmt):
    handleIfStmt(c, it, before1)
  return true

proc matchWhileStmt(c: var Context; it: var Item): bool =
  when declared(handleWhileStmt):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, WhileT):
    if not matchExpr(c, it):
      error(c, it, "Expr expected")
    if not matchStmtList(c, it):
      error(c, it, "StmtList expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleWhileStmt):
    handleWhileStmt(c, it, before1)
  return true

proc matchCaseStmt(c: var Context; it: var Item): bool =
  when declared(handleCaseStmt):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, CaseT):
    if not matchExpr(c, it):
      error(c, it, "Expr expected")
    var om3 = false
    while not peekParRi(c, it):
      var kw4 = false
      if isTag(c, it, OfT):
        if not matchBranchRanges(c, it):
          error(c, it, "BranchRanges expected")
        if not matchStmtList(c, it):
          error(c, it, "StmtList expected")
        kw4 = matchParRi(c, it)
      if not kw4:
        break
      else:
        om3 = true
    if not om3:
      error(c, it, "invalid CaseStmt")
    var kw5 = false
    if isTag(c, it, ElseT):
      if not matchStmtList(c, it):
        error(c, it, "StmtList expected")
      kw5 = matchParRi(c, it)
    discard kw5
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleCaseStmt):
    handleCaseStmt(c, it, before1)
  return true

proc matchLabelStmt(c: var Context; it: var Item): bool =
  when declared(handleLabelStmt):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, LabT):
    var sym3 = declareSym(c, it)
    if not success(sym3):
      error(c, it, "SYMBOLDEF expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleLabelStmt):
    handleLabelStmt(c, it, before1)
  return true

proc matchJumpStmt(c: var Context; it: var Item): bool =
  when declared(handleJumpStmt):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, JmpT):
    if not lookupSym(c, it):
      error(c, it, "SYMBOL expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleJumpStmt):
    handleJumpStmt(c, it, before1)
  return true

proc matchScopeStmt(c: var Context; it: var Item): bool =
  when declared(handleScopeStmt):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, ScopeT):
    if not matchStmtList(c, it):
      error(c, it, "StmtList expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleScopeStmt):
    handleScopeStmt(c, it, before1)
  return true

proc matchDiscardStmt(c: var Context; it: var Item): bool =
  when declared(handleDiscardStmt):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, DiscardT):
    if not matchExpr(c, it):
      error(c, it, "Expr expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleDiscardStmt):
    handleDiscardStmt(c, it, before1)
  return true

proc matchStmt(c: var Context; it: var Item): bool =
  when declared(handleStmt):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchCall(c, it):
      or2 = true
      break or3
    if matchCallCanRaise(c, it):
      or2 = true
      break or3
    if matchVarDecl(c, it):
      or2 = true
      break or3
    if matchConstDecl(c, it):
      or2 = true
      break or3
    if matchEmitStmt(c, it):
      or2 = true
      break or3
    if matchTryStmt(c, it):
      or2 = true
      break or3
    if matchRaiseStmt(c, it):
      or2 = true
      break or3
    if matchAsgnStmt(c, it):
      or2 = true
      break or3
    if matchKeepOverflowStmt(c, it):
      or2 = true
      break or3
    if matchIfStmt(c, it):
      or2 = true
      break or3
    if matchWhileStmt(c, it):
      or2 = true
      break or3
    if isTag(c, it, BreakT):
      or2 = true
      break or3
    if matchCaseStmt(c, it):
      or2 = true
      break or3
    if matchLabelStmt(c, it):
      or2 = true
      break or3
    if matchJumpStmt(c, it):
      or2 = true
      break or3
    if matchScopeStmt(c, it):
      or2 = true
      break or3
    var kw4 = false
    if isTag(c, it, RetT):
      var or5 = false
      block or6:
        if matchEmpty(c, it):
          or5 = true
          break or6
        if matchExpr(c, it):
          or5 = true
          break or6
      if not or5:
        error(c, it, "invalid Stmt")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
    if matchDiscardStmt(c, it):
      or2 = true
      break or3
  if not or2: return false
  when declared(handleStmt):
    handleStmt(c, it, before1)
  return true

proc matchStmtList(c: var Context; it: var Item): bool =
  when declared(handleStmtList):
    var before1 = save(c, it)
  openScope(c)
  try:
    var kw2 = false
    if isTag(c, it, StmtsT):
      var zm3 = true
      while not peekParRi(c, it):
        if not matchStmt(c, it):
          zm3 = false
          break
      if not zm3:
        error(c, it, "invalid StmtList")
      kw2 = matchParRi(c, it)
    if not kw2: return false
  finally:
    closeScope(c)
  
  when declared(handleStmtList):
    handleStmtList(c, it, before1)
  return true

proc matchParam(c: var Context; it: var Item): bool =
  when declared(handleParam):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, ParamT):
    var sym3 = declareSym(c, it)
    if not success(sym3):
      error(c, it, "SYMBOLDEF expected")
    if not matchParamPragmas(c, it):
      error(c, it, "ParamPragmas expected")
    if not matchType(c, it):
      error(c, it, "Type expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleParam):
    handleParam(c, it, before1)
  return true

proc matchParams(c: var Context; it: var Item): bool =
  when declared(handleParams):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchEmpty(c, it):
      or2 = true
      break or3
    var zm4 = true
    while not peekParRi(c, it):
      var kw5 = false
      if isTag(c, it, ParamsT):
        if not matchParam(c, it):
          error(c, it, "Param expected")
        kw5 = matchParRi(c, it)
      if not kw5:
        zm4 = false
        break
    if zm4:
      or2 = true
      break or3
  if not or2: return false
  when declared(handleParams):
    handleParams(c, it, before1)
  return true

proc matchProcDecl(c: var Context; it: var Item): bool =
  when declared(handleProcDecl):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, ProcT):
    var sym3 = declareSym(c, it)
    if not success(sym3):
      error(c, it, "SYMBOLDEF expected")
    if not matchParams(c, it):
      error(c, it, "Params expected")
    if not matchType(c, it):
      error(c, it, "Type expected")
    if not matchProcPragmas(c, it):
      error(c, it, "ProcPragmas expected")
    var or4 = false
    block or5:
      if matchEmpty(c, it):
        or4 = true
        break or5
      if matchStmtList(c, it):
        or4 = true
        break or5
    if not or4:
      error(c, it, "invalid ProcDecl")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleProcDecl):
    handleProcDecl(c, it, before1)
  return true

proc matchFieldDecl(c: var Context; it: var Item): bool =
  when declared(handleFieldDecl):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, FldT):
    var sym3 = declareSym(c, it)
    if not success(sym3):
      error(c, it, "SYMBOLDEF expected")
    if not matchFieldPragmas(c, it):
      error(c, it, "FieldPragmas expected")
    if not matchType(c, it):
      error(c, it, "Type expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleFieldDecl):
    handleFieldDecl(c, it, before1)
  return true

proc matchUnionDecl(c: var Context; it: var Item): bool =
  when declared(handleUnionDecl):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, UnionT):
    if not matchEmpty(c, it):
      error(c, it, "in rule UnionDecl: <empty node> expected")
    var zm3 = true
    while not peekParRi(c, it):
      if not matchFieldDecl(c, it):
        zm3 = false
        break
    if not zm3:
      error(c, it, "invalid UnionDecl")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleUnionDecl):
    handleUnionDecl(c, it, before1)
  return true

proc matchObjDecl(c: var Context; it: var Item): bool =
  when declared(handleObjDecl):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, ObjectT):
    var or3 = false
    block or4:
      if matchEmpty(c, it):
        or3 = true
        break or4
      if matchType(c, it):
        or3 = true
        break or4
    if not or3:
      error(c, it, "invalid ObjDecl")
    var zm5 = true
    while not peekParRi(c, it):
      if not matchFieldDecl(c, it):
        zm5 = false
        break
    if not zm5:
      error(c, it, "invalid ObjDecl")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleObjDecl):
    handleObjDecl(c, it, before1)
  return true

proc matchEnumFieldDecl(c: var Context; it: var Item): bool =
  when declared(handleEnumFieldDecl):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, EfldT):
    var sym3 = declareSym(c, it)
    if not success(sym3):
      error(c, it, "SYMBOLDEF expected")
    var or4 = false
    block or5:
      if matchIntLit(c, it):
        or4 = true
        break or5
      if matchUIntLit(c, it):
        or4 = true
        break or5
      if matchCharLit(c, it):
        or4 = true
        break or5
    if not or4:
      error(c, it, "invalid EnumFieldDecl")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleEnumFieldDecl):
    handleEnumFieldDecl(c, it, before1)
  return true

proc matchEnumDecl(c: var Context; it: var Item): bool =
  when declared(handleEnumDecl):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, EnumT):
    if not matchType(c, it):
      error(c, it, "Type expected")
    var om3 = false
    while not peekParRi(c, it):
      if not matchEnumFieldDecl(c, it):
        break
      else:
        om3 = true
    if not om3:
      error(c, it, "invalid EnumDecl")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleEnumDecl):
    handleEnumDecl(c, it, before1)
  return true

proc matchProcType(c: var Context; it: var Item): bool =
  when declared(handleProcType):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, ProctypeT):
    if not matchEmpty(c, it):
      error(c, it, "in rule ProcType: <empty node> expected")
    if not matchParams(c, it):
      error(c, it, "Params expected")
    if not matchType(c, it):
      error(c, it, "Type expected")
    if not matchProcTypePragmas(c, it):
      error(c, it, "ProcTypePragmas expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleProcType):
    handleProcType(c, it, before1)
  return true

proc matchIntQualifier(c: var Context; it: var Item): bool =
  when declared(handleIntQualifier):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if isTag(c, it, AtomicT):
      or2 = true
      break or3
    if isTag(c, it, RoT):
      or2 = true
      break or3
  if not or2: return false
  when declared(handleIntQualifier):
    handleIntQualifier(c, it, before1)
  return true

proc matchPtrQualifier(c: var Context; it: var Item): bool =
  when declared(handlePtrQualifier):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if isTag(c, it, AtomicT):
      or2 = true
      break or3
    if isTag(c, it, RoT):
      or2 = true
      break or3
    if isTag(c, it, RestrictT):
      or2 = true
      break or3
  if not or2: return false
  when declared(handlePtrQualifier):
    handlePtrQualifier(c, it, before1)
  return true

proc matchType(c: var Context; it: var Item): bool =
  when declared(handleType):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if lookupSym(c, it):
      or2 = true
      break or3
    var kw4 = false
    if isTag(c, it, IT):
      if not matchIntBits(c, it):
        error(c, it, "IntBits expected")
      var zm5 = true
      while not peekParRi(c, it):
        if not matchIntQualifier(c, it):
          zm5 = false
          break
      if not zm5:
        error(c, it, "invalid Type")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
    var kw6 = false
    if isTag(c, it, UT):
      if not matchIntBits(c, it):
        error(c, it, "IntBits expected")
      var zm7 = true
      while not peekParRi(c, it):
        if not matchIntQualifier(c, it):
          zm7 = false
          break
      if not zm7:
        error(c, it, "invalid Type")
      kw6 = matchParRi(c, it)
    if kw6:
      or2 = true
      break or3
    var kw8 = false
    if isTag(c, it, FT):
      if not matchIntBits(c, it):
        error(c, it, "IntBits expected")
      var zm9 = true
      while not peekParRi(c, it):
        if not matchIntQualifier(c, it):
          zm9 = false
          break
      if not zm9:
        error(c, it, "invalid Type")
      kw8 = matchParRi(c, it)
    if kw8:
      or2 = true
      break or3
    var kw10 = false
    if isTag(c, it, CT):
      if not matchIntBits(c, it):
        error(c, it, "IntBits expected")
      var zm11 = true
      while not peekParRi(c, it):
        if not matchIntQualifier(c, it):
          zm11 = false
          break
      if not zm11:
        error(c, it, "invalid Type")
      kw10 = matchParRi(c, it)
    if kw10:
      or2 = true
      break or3
    var kw12 = false
    if isTag(c, it, BoolT):
      var zm13 = true
      while not peekParRi(c, it):
        if not matchIntQualifier(c, it):
          zm13 = false
          break
      if not zm13:
        error(c, it, "invalid Type")
      kw12 = matchParRi(c, it)
    if kw12:
      or2 = true
      break or3
    if isTag(c, it, VoidT):
      or2 = true
      break or3
    var kw14 = false
    if isTag(c, it, PtrT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      var zm15 = true
      while not peekParRi(c, it):
        if not matchPtrQualifier(c, it):
          zm15 = false
          break
      if not zm15:
        error(c, it, "invalid Type")
      kw14 = matchParRi(c, it)
    if kw14:
      or2 = true
      break or3
    var kw16 = false
    if isTag(c, it, FlexarrayT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      kw16 = matchParRi(c, it)
    if kw16:
      or2 = true
      break or3
    var kw17 = false
    if isTag(c, it, AptrT):
      if not matchType(c, it):
        error(c, it, "Type expected")
      var zm18 = true
      while not peekParRi(c, it):
        if not matchPtrQualifier(c, it):
          zm18 = false
          break
      if not zm18:
        error(c, it, "invalid Type")
      kw17 = matchParRi(c, it)
    if kw17:
      or2 = true
      break or3
    if matchProcType(c, it):
      or2 = true
      break or3
  if not or2: return false
  when declared(handleType):
    handleType(c, it, before1)
  return true

proc matchArrayDecl(c: var Context; it: var Item): bool =
  when declared(handleArrayDecl):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, ArrayT):
    if not matchType(c, it):
      error(c, it, "Type expected")
    if not matchExpr(c, it):
      error(c, it, "Expr expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleArrayDecl):
    handleArrayDecl(c, it, before1)
  return true

proc matchTypeDecl(c: var Context; it: var Item): bool =
  when declared(handleTypeDecl):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, TypeT):
    var sym3 = declareSym(c, it)
    if not success(sym3):
      error(c, it, "SYMBOLDEF expected")
    if not matchTypePragmas(c, it):
      error(c, it, "TypePragmas expected")
    var or4 = false
    block or5:
      if matchProcType(c, it):
        or4 = true
        break or5
      if matchObjDecl(c, it):
        or4 = true
        break or5
      if matchUnionDecl(c, it):
        or4 = true
        break or5
      if matchEnumDecl(c, it):
        or4 = true
        break or5
      if matchArrayDecl(c, it):
        or4 = true
        break or5
    if not or4:
      error(c, it, "invalid TypeDecl")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleTypeDecl):
    handleTypeDecl(c, it, before1)
  return true

proc matchCallingConvention(c: var Context; it: var Item): bool =
  when declared(handleCallingConvention):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if isTag(c, it, CdeclT):
      or2 = true
      break or3
    if isTag(c, it, StdcallT):
      or2 = true
      break or3
    if isTag(c, it, SafecallT):
      or2 = true
      break or3
    if isTag(c, it, SyscallT):
      or2 = true
      break or3
    if isTag(c, it, FastcallT):
      or2 = true
      break or3
    if isTag(c, it, ThiscallT):
      or2 = true
      break or3
    if isTag(c, it, NoconvT):
      or2 = true
      break or3
    if isTag(c, it, MemberT):
      or2 = true
      break or3
  if not or2: return false
  when declared(handleCallingConvention):
    handleCallingConvention(c, it, before1)
  return true

proc matchAttribute(c: var Context; it: var Item): bool =
  when declared(handleAttribute):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, AttrT):
    if not matchStringLit(c, it):
      error(c, it, "STRINGLITERAL expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleAttribute):
    handleAttribute(c, it, before1)
  return true

proc matchIdentifier(c: var Context; it: var Item): bool =
  when declared(handleIdentifier):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if lookupSym(c, it):
      or2 = true
      break or3
    if matchIdent(c, it):
      or2 = true
      break or3
  if not or2: return false
  when declared(handleIdentifier):
    handleIdentifier(c, it, before1)
  return true

proc matchProcPragma(c: var Context; it: var Item): bool =
  when declared(handleProcPragma):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if isTag(c, it, InlineT):
      or2 = true
      break or3
    if isTag(c, it, NoinlineT):
      or2 = true
      break or3
    if matchCallingConvention(c, it):
      or2 = true
      break or3
    if isTag(c, it, VarargsT):
      or2 = true
      break or3
    var kw4 = false
    if isTag(c, it, WasT):
      if not matchIdentifier(c, it):
        error(c, it, "Identifier expected")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
    if isTag(c, it, SelectanyT):
      or2 = true
      break or3
    if isTag(c, it, RaisesT):
      or2 = true
      break or3
    if isTag(c, it, ErrsT):
      or2 = true
      break or3
    if matchAttribute(c, it):
      or2 = true
      break or3
  if not or2: return false
  when declared(handleProcPragma):
    handleProcPragma(c, it, before1)
  return true

proc matchProcTypePragma(c: var Context; it: var Item): bool =
  when declared(handleProcTypePragma):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchCallingConvention(c, it):
      or2 = true
      break or3
    if isTag(c, it, VarargsT):
      or2 = true
      break or3
    if matchAttribute(c, it):
      or2 = true
      break or3
  if not or2: return false
  when declared(handleProcTypePragma):
    handleProcTypePragma(c, it, before1)
  return true

proc matchProcTypePragmas(c: var Context; it: var Item): bool =
  when declared(handleProcTypePragmas):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchEmpty(c, it):
      or2 = true
      break or3
    var kw4 = false
    if isTag(c, it, PragmasT):
      var om5 = false
      while not peekParRi(c, it):
        if not matchProcTypePragma(c, it):
          break
        else:
          om5 = true
      if not om5:
        error(c, it, "invalid ProcTypePragmas")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
  if not or2: return false
  when declared(handleProcTypePragmas):
    handleProcTypePragmas(c, it, before1)
  return true

proc matchProcPragmas(c: var Context; it: var Item): bool =
  when declared(handleProcPragmas):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchEmpty(c, it):
      or2 = true
      break or3
    var kw4 = false
    if isTag(c, it, PragmasT):
      var om5 = false
      while not peekParRi(c, it):
        if not matchProcPragma(c, it):
          break
        else:
          om5 = true
      if not om5:
        error(c, it, "invalid ProcPragmas")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
  if not or2: return false
  when declared(handleProcPragmas):
    handleProcPragmas(c, it, before1)
  return true

proc matchCommonPragma(c: var Context; it: var Item): bool =
  when declared(handleCommonPragma):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    var kw4 = false
    if isTag(c, it, AlignT):
      if not matchIntLit(c, it):
        error(c, it, "INTLIT expected")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
    var kw5 = false
    if isTag(c, it, WasT):
      if not matchIdentifier(c, it):
        error(c, it, "Identifier expected")
      kw5 = matchParRi(c, it)
    if kw5:
      or2 = true
      break or3
    if matchAttribute(c, it):
      or2 = true
      break or3
  if not or2: return false
  when declared(handleCommonPragma):
    handleCommonPragma(c, it, before1)
  return true

proc matchVarPragma(c: var Context; it: var Item): bool =
  when declared(handleVarPragma):
    var before1 = save(c, it)
  if not matchCommonPragma(c, it): return false
  when declared(handleVarPragma):
    handleVarPragma(c, it, before1)
  return true

proc matchVarPragmas(c: var Context; it: var Item): bool =
  when declared(handleVarPragmas):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchEmpty(c, it):
      or2 = true
      break or3
    var kw4 = false
    if isTag(c, it, PragmasT):
      var om5 = false
      while not peekParRi(c, it):
        if not matchVarPragma(c, it):
          break
        else:
          om5 = true
      if not om5:
        error(c, it, "invalid VarPragmas")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
  if not or2: return false
  when declared(handleVarPragmas):
    handleVarPragmas(c, it, before1)
  return true

proc matchParamPragma(c: var Context; it: var Item): bool =
  when declared(handleParamPragma):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    var kw4 = false
    if isTag(c, it, WasT):
      if not matchIdentifier(c, it):
        error(c, it, "Identifier expected")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
    if matchAttribute(c, it):
      or2 = true
      break or3
  if not or2: return false
  when declared(handleParamPragma):
    handleParamPragma(c, it, before1)
  return true

proc matchParamPragmas(c: var Context; it: var Item): bool =
  when declared(handleParamPragmas):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchEmpty(c, it):
      or2 = true
      break or3
    var kw4 = false
    if isTag(c, it, PragmasT):
      var om5 = false
      while not peekParRi(c, it):
        if not matchParamPragma(c, it):
          break
        else:
          om5 = true
      if not om5:
        error(c, it, "invalid ParamPragmas")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
  if not or2: return false
  when declared(handleParamPragmas):
    handleParamPragmas(c, it, before1)
  return true

proc matchFieldPragma(c: var Context; it: var Item): bool =
  when declared(handleFieldPragma):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchCommonPragma(c, it):
      or2 = true
      break or3
    var kw4 = false
    if isTag(c, it, BitsT):
      if not matchIntLit(c, it):
        error(c, it, "INTLIT expected")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
  if not or2: return false
  when declared(handleFieldPragma):
    handleFieldPragma(c, it, before1)
  return true

proc matchFieldPragmas(c: var Context; it: var Item): bool =
  when declared(handleFieldPragmas):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, PragmasT):
    var om3 = false
    while not peekParRi(c, it):
      if not matchFieldPragma(c, it):
        break
      else:
        om3 = true
    if not om3:
      error(c, it, "invalid FieldPragmas")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleFieldPragmas):
    handleFieldPragmas(c, it, before1)
  return true

proc matchTypePragma(c: var Context; it: var Item): bool =
  when declared(handleTypePragma):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchCommonPragma(c, it):
      or2 = true
      break or3
    var kw4 = false
    if isTag(c, it, VectorT):
      if not matchIntLit(c, it):
        error(c, it, "INTLIT expected")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
  if not or2: return false
  when declared(handleTypePragma):
    handleTypePragma(c, it, before1)
  return true

proc matchTypePragmas(c: var Context; it: var Item): bool =
  when declared(handleTypePragmas):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchEmpty(c, it):
      or2 = true
      break or3
    var kw4 = false
    if isTag(c, it, PragmasT):
      var om5 = false
      while not peekParRi(c, it):
        if not matchTypePragma(c, it):
          break
        else:
          om5 = true
      if not om5:
        error(c, it, "invalid TypePragmas")
      kw4 = matchParRi(c, it)
    if kw4:
      or2 = true
      break or3
  if not or2: return false
  when declared(handleTypePragmas):
    handleTypePragmas(c, it, before1)
  return true

proc matchExternDecl(c: var Context; it: var Item): bool =
  when declared(handleExternDecl):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, ImpT):
    var or3 = false
    block or4:
      if matchProcDecl(c, it):
        or3 = true
        break or4
      if matchVarDecl(c, it):
        or3 = true
        break or4
      if matchConstDecl(c, it):
        or3 = true
        break or4
    if not or3:
      error(c, it, "invalid ExternDecl")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleExternDecl):
    handleExternDecl(c, it, before1)
  return true

proc matchIgnoreDecl(c: var Context; it: var Item): bool =
  when declared(handleIgnoreDecl):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, NodeclT):
    var or3 = false
    block or4:
      if matchProcDecl(c, it):
        or3 = true
        break or4
      if matchVarDecl(c, it):
        or3 = true
        break or4
      if matchConstDecl(c, it):
        or3 = true
        break or4
    if not or3:
      error(c, it, "invalid IgnoreDecl")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleIgnoreDecl):
    handleIgnoreDecl(c, it, before1)
  return true

proc matchInclude(c: var Context; it: var Item): bool =
  when declared(handleInclude):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, InclT):
    if not matchStringLit(c, it):
      error(c, it, "STRINGLITERAL expected")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleInclude):
    handleInclude(c, it, before1)
  return true

proc matchTopLevelConstruct(c: var Context; it: var Item): bool =
  when declared(handleTopLevelConstruct):
    var before1 = save(c, it)
  var or2 = false
  block or3:
    if matchExternDecl(c, it):
      or2 = true
      break or3
    if matchIgnoreDecl(c, it):
      or2 = true
      break or3
    if matchProcDecl(c, it):
      or2 = true
      break or3
    if matchVarDecl(c, it):
      or2 = true
      break or3
    if matchConstDecl(c, it):
      or2 = true
      break or3
    if matchTypeDecl(c, it):
      or2 = true
      break or3
    if matchInclude(c, it):
      or2 = true
      break or3
    if matchEmitStmt(c, it):
      or2 = true
      break or3
    if matchCall(c, it):
      or2 = true
      break or3
    if matchCallCanRaise(c, it):
      or2 = true
      break or3
    if matchTryStmt(c, it):
      or2 = true
      break or3
    if matchRaiseStmt(c, it):
      or2 = true
      break or3
    if matchAsgnStmt(c, it):
      or2 = true
      break or3
    if matchKeepOverflowStmt(c, it):
      or2 = true
      break or3
    if matchIfStmt(c, it):
      or2 = true
      break or3
    if matchWhileStmt(c, it):
      or2 = true
      break or3
    if matchCaseStmt(c, it):
      or2 = true
      break or3
    if matchLabelStmt(c, it):
      or2 = true
      break or3
    if matchJumpStmt(c, it):
      or2 = true
      break or3
    if matchScopeStmt(c, it):
      or2 = true
      break or3
    if matchDiscardStmt(c, it):
      or2 = true
      break or3
  if not or2: return false
  when declared(handleTopLevelConstruct):
    handleTopLevelConstruct(c, it, before1)
  return true

proc matchModule(c: var Context; it: var Item): bool =
  when declared(handleModule):
    var before1 = save(c, it)
  var kw2 = false
  if isTag(c, it, StmtsT):
    var zm3 = true
    while not peekParRi(c, it):
      if not matchTopLevelConstruct(c, it):
        zm3 = false
        break
    if not zm3:
      error(c, it, "invalid Module")
    kw2 = matchParRi(c, it)
  if not kw2: return false
  when declared(handleModule):
    handleModule(c, it, before1)
  return true
