def Expression(self):
        g = self.Term()
        first = True
        while self.WeakSeparator(Scanner.bar_Sym, 19, 20):
            g2 = self.Term()
            if first:
                Graph.MakeFirstAlt(g)
                first = False
            Graph.MakeAlternative(g, g2)

        return g
    def TokenExpr(self):
        g = self.TokenTerm()
        first = True
        while self.WeakSeparator(Scanner.bar_Sym, 6, 7):
            g2 = self.TokenTerm()
            if first:
                Graph.MakeFirstAlt(g)
                first = False
            Graph.MakeAlternative(g, g2)

        return g
    def TokenTerm(self):
        g = self.TokenFactor()
        while self.StartOf(6):
            g2 = self.TokenFactor()
            Graph.MakeSequence(g, g2)

        if (self.la.kind == Scanner.CONTEXT_Sym):
            self.Get()
            self.Expect(Scanner.lparen_Sym)
            g2 = self.TokenExpr()
            Graph.SetContextTrans(g2.l)
            Graph.MakeSequence(g, g2)
            self.Expect(Scanner.rparen_Sym)
        return g
 def TokenFactor(self):
     g = None
     if self.la.kind == Scanner.ident_Sym or self.la.kind == Scanner.string_Sym:
         s = self.Sym()
         name, kind = s
         if kind == self.id:
             c = CharClass.Find(name)
             if c is None:
                 self.SemErr("undefined name")
                 c = CharClass(s.name, set())
             p = Node(Node.clas, None, 0)
             p.val = c.n
             g = Graph(p)
             self.tokenString = self.noString
         else:  # str
             g = Graph.StrToGraph(name)
             if self.tokenString is None:
                 self.tokenString = name
             else:
                 self.tokenString = self.noString
     elif self.la.kind == Scanner.lparen_Sym:
         self.Get()
         g = self.TokenExpr()
         self.Expect(Scanner.rparen_Sym)
     elif self.la.kind == Scanner.lbrack_Sym:
         self.Get()
         g = self.TokenExpr()
         self.Expect(Scanner.rbrack_Sym)
         Graph.MakeOption(g)
     elif self.la.kind == Scanner.lbrace_Sym:
         self.Get()
         g = self.TokenExpr()
         self.Expect(Scanner.rbrace_Sym)
         Graph.MakeIteration(g)
     else:
         self.SynErr(76)
     if g is None:  # invalid start of TokenFactor
         g = Graph(Node(Node.eps, None, 0))
     return g
    def Term(self):
        rslv = None
        g = None
        if self.StartOf(22):
            if (self.la.kind == Scanner.IF_Sym):
                rslv = Node(Node.rslv, None, self.la.line)
                rslv.pos = self.Resolver()
                g = Graph(rslv)
            g2 = self.Factor()
            if rslv is not None:
                Graph.MakeSequence(g, g2)
            else:
                g = g2
            while self.StartOf(23):
                g2 = self.Factor()
                Graph.MakeSequence(g, g2)

        elif self.StartOf(24):
            g = Graph(Node(Node.eps, None, 0))
        else:
            self.SynErr(67)
        if g is None:  # invalid start of Term
            g = Graph(Node(Node.eps, None, 0))
        return g
    def TokenDecl(self, typ):
        s = self.Sym()
        name, kind = s
        sym = Symbol.Find(name)
        if sym is not None:
            self.SemErr("name declared twice")
        else:
            sym = Symbol(typ, name, self.token.line)
            sym.tokenKind = Symbol.fixedToken
        self.tokenString = None
        while not (self.StartOf(4)):
            self.SynErr(52)
            self.Get()
        if self.la.kind == Scanner.equal_Sym:
            self.Get()
            g = self.TokenExpr()
            self.Expect(Scanner.point_Sym)
            if kind == self.str:
                self.SemErr("a literal must not be declared with a structure")
            Graph.Finish(g)
            if (self.tokenString is None) or (self.tokenString
                                              == self.noString):
                DFA.ConvertToStates(g.l, sym)
            else:  # TokenExpr is a single string
                if Tab.literals.get(self.tokenString) is not None:
                    self.SemErr("token string declared twice")
                Tab.literals[self.tokenString] = sym
                DFA.MatchLiteral(self.tokenString, sym)

        elif self.StartOf(5):
            if kind == self.id:
                genScanner = False
            else:
                DFA.MatchLiteral(sym.name, sym)
        else:
            self.SynErr(53)
        if (self.la.kind == Scanner.lparenpoint_Sym):
            sym.semPos = self.SemText()
            if typ != Node.pr:
                self.SemErr("semantic action not allowed here")
 def Factor(self):
     weak = False
     g = None
     if self.la.kind == Scanner.ident_Sym or self.la.kind == Scanner.string_Sym or self.la.kind == Scanner.WEAK_Sym:
         if (self.la.kind == Scanner.WEAK_Sym):
             self.Get()
             weak = True
         s = self.Sym()
         name, kind = s
         sym = Symbol.Find(name)
         if (sym is None) and (kind == self.str):
             sym = Tab.literals.get(name)
         undef = (sym is None)
         if undef:
             if kind == self.id:
                 sym = Symbol(Node.nt, name, 0)  # forward nt
             elif self.genScanner:
                 sym = Symbol(Node.t, name, self.token.line)
                 DFA.MatchLiteral(sym.name, sym)
             else:  # undefined string in production
                 self.SemErr("undefined string in production")
                 sym = Tab.eofSy  # dummy
         typ = sym.typ
         if (typ != Node.t) and (typ != Node.nt):
             self.SemErr("this symbol kind is not allowed in a production")
         if weak:
             if typ == Node.t:
                 typ = Node.wt
             else:
                 self.SemErr("only terminals may be weak")
         p = Node(typ, sym, self.token.line)
         g = Graph(p)
         if (self.la.kind == Scanner.less_Sym
                 or self.la.kind == Scanner.lesspoint_Sym):
             self.Attribs(p)
             if kind != self.id:
                 self.SemErr("a literal must not have attributes")
         if undef:
             sym.attrPos = p.pos  # dummy
             sym.retVar = p.retVar  # AH - dummy
         elif ((p.pos is None) !=
               (sym.attrPos is None)) or ((p.retVar is None) !=
                                          (sym.retVar is None)):
             self.SemErr(
                 "attribute mismatch between declaration and use of this symbol"
             )
     elif self.la.kind == Scanner.lparen_Sym:
         self.Get()
         g = self.Expression()
         self.Expect(Scanner.rparen_Sym)
     elif self.la.kind == Scanner.lbrack_Sym:
         self.Get()
         g = self.Expression()
         self.Expect(Scanner.rbrack_Sym)
         Graph.MakeOption(g)
     elif self.la.kind == Scanner.lbrace_Sym:
         self.Get()
         g = self.Expression()
         self.Expect(Scanner.rbrace_Sym)
         Graph.MakeIteration(g)
     elif self.la.kind == Scanner.lparenpoint_Sym:
         pos = self.SemText()
         p = Node(Node.sem, None, 0)
         p.pos = pos
         g = Graph(p)
     elif self.la.kind == Scanner.ANY_Sym:
         self.Get()
         p = Node(Node.any, None, 0)  # p.set is set in Tab.SetupAnys
         g = Graph(p)
     elif self.la.kind == Scanner.SYNC_Sym:
         self.Get()
         p = Node(Node.sync, None, 0)
         g = Graph(p)
     else:
         self.SynErr(68)
     if g is None:  # invalid start of Factor
         g = Graph(Node(Node.eps, None, 0))
     return g
    def Coco(self):
        g = Graph()
        g1 = Graph()
        g2 = Graph()
        s = set()
        if (self.la.kind == Scanner.from_Sym
                or self.la.kind == Scanner.import_Sym):
            ParserGen.usingPos = self.Imports()
        self.Expect(Scanner.COMPILER_Sym)
        self.genScanner = True
        Tab.ignored = set()
        self.Expect(Scanner.ident_Sym)
        gramName = self.token.val
        beg = self.la.pos
        while self.StartOf(1):
            self.Get()

        Tab.semDeclPos = Position(self.scanner.buffer, beg, self.la.pos - beg,
                                  0)
        if (self.la.kind == Scanner.IGNORECASE_Sym):
            self.Get()
            DFA.ignoreCase = True
        if (self.la.kind == Scanner.CHARACTERS_Sym):
            self.Get()
            while self.la.kind == Scanner.ident_Sym:
                self.SetDecl()

        if (self.la.kind == Scanner.TOKENS_Sym):
            self.Get()
            while self.la.kind == Scanner.ident_Sym or self.la.kind == Scanner.string_Sym:
                self.TokenDecl(Node.t)

        if (self.la.kind == Scanner.NAMES_Sym):
            self.Get()
            while self.la.kind == Scanner.ident_Sym:
                self.NameDecl()

        if (self.la.kind == Scanner.PRAGMAS_Sym):
            self.Get()
            while self.la.kind == Scanner.ident_Sym or self.la.kind == Scanner.string_Sym:
                self.TokenDecl(Node.pr)

        while self.la.kind == Scanner.COMMENTS_Sym:
            self.Get()
            nested = False
            self.Expect(Scanner.FROM_Sym)
            g1 = self.TokenExpr()
            self.Expect(Scanner.TO_Sym)
            g2 = self.TokenExpr()
            if (self.la.kind == Scanner.NESTED_Sym):
                self.Get()
                nested = True
            Comment(g1.l, g2.l, nested)

        while self.la.kind == Scanner.IGNORE_Sym:
            self.Get()
            s = self.Set()
            Tab.ignored |= s  # set union

        while not (self.la.kind == Scanner.EOF_SYM
                   or self.la.kind == Scanner.PRODUCTIONS_Sym):
            self.SynErr(49)
            self.Get()
        self.Expect(Scanner.PRODUCTIONS_Sym)
        if self.genScanner:
            DFA.MakeDeterministic()
        Graph.DeleteNodes()
        while self.la.kind == Scanner.ident_Sym:
            self.Get()
            sym = Symbol.Find(self.token.val)
            undef = (sym is None)
            if undef:
                sym = Symbol(Node.nt, self.token.val, self.token.line)
            else:
                if sym.typ == Node.nt:
                    if sym.graph is not None:
                        self.SemErr("name declared twice")
                else:
                    self.SemErr(
                        "this symbol kind not allowed on left side of production"
                    )
                sym.line = self.token.line
            noAttrs = (sym.attrPos is None)
            sym.attrPos = None
            noRet = (sym.retVar is None)
            sym.retVar = None
            if (self.la.kind == Scanner.less_Sym
                    or self.la.kind == Scanner.lesspoint_Sym):
                self.AttrDecl(sym)
            if not undef:
                if noAttrs != (sym.attrPos is None) or (noRet !=
                                                        (sym.retVar is None)):
                    self.SemErr(
                        "attribute mismatch between declaration and use of this symbol"
                    )
            if (self.la.kind == Scanner.lparenpoint_Sym):
                sym.semPos = self.SemText()
            self.ExpectWeak(Scanner.equal_Sym, 2)
            g = self.Expression()
            sym.graph = g.l
            Graph.Finish(g)
            self.ExpectWeak(Scanner.point_Sym, 3)

        self.Expect(Scanner.END_Sym)
        self.Expect(Scanner.ident_Sym)
        if gramName != self.token.val:
            self.SemErr("name does not match grammar name")
        Tab.gramSy = Symbol.Find(gramName)
        if Tab.gramSy is None:
            self.SemErr("missing production for grammar name")
        else:
            sym = Tab.gramSy
            if sym.attrPos is not None:
                self.SemErr("grammar symbol must not have attributes")
        Tab.noSym = Symbol(Node.t, "???", 0)  #noSym gets highest number
        Tab.SetupAnys()
        Tab.RenumberPragmas()
        if Tab.ddt[2]:
            Node.PrintNodes()
        if Errors.count == 0:
            sys.stdout.write("checking\n")
            Tab.CompSymbolSets()
            if Tab.ddt[7]:
                Tab.XRef()
            if Tab.GrammarOk():
                if not Tab.ddt[9]:
                    sys.stdout.write("parser")
                    ParserGen.WriteParser(Tab.ddt[10])
                    if self.genScanner:
                        sys.stdout.write(" + scanner")
                        DFA.WriteScanner(Tab.ddt[10])
                        if Tab.ddt[0]:
                            DFA.PrintStates()
                    if Tab.ddt[11]:
                        sys.stdout.write(" + driver")
                        DriverGen.WriteDriver()
                    sys.stdout.write(" generated\n")
                if Tab.ddt[8]:
                    ParserGen.WriteStatistics()
        if Tab.ddt[6]:
            Tab.PrintSymbolTable()
        self.Expect(Scanner.point_Sym)