Esempio n. 1
0
    def test_nodes(self):
        root = TextNode(Nonterminal("Root"))
        bos = BOS(Terminal(""))
        eos = EOS(FinishSymbol())
        a = TextNode(Terminal("a"))
        b = TextNode(Terminal("b"))
        nB = TextNode(Nonterminal("B"))
        nB.set_children([b])
        root.set_children([bos, a, nB, eos])

        a.next_term = b
        b.next_term = eos

        l = Lexer([("name", "[a-z]+")])
        assert l.treelex(a) == [("ab", "name", 0)]
Esempio n. 2
0
    def parse_after(self, la, split=None, maxtoks=1, maxdist=0):
        """Checks if la can be parsed in the current state. If la is whitespace,
        continue until we can parse the next non-whitespace token."""
        parsed_tokens = 0
        parsed_distance = 0
        if split:
            token = self.lexer.lex(la.prev_term.symbol.name[split:])
            tmpla = la
            la = TextNode(Terminal(token[0][1]))
            la.next_term = tmpla
        while True:
            lookup = get_lookup(la)
            element = self.syntaxtable.lookup(self.state[-1], lookup)

            # If we see the errornode here and the parse table action is
            # either Shift or Accept, then the inserted language box has fixed
            # the error without wrapping it inside the box
            if la is self.errornode and type(element) in [Shift, Accept]:
                self.seen_error = True

            if type(element) is Reduce:
                for i in range(element.amount()):
                    self.state.pop()
                goto = self.syntaxtable.lookup(self.state[-1],
                                               element.action.left)
                assert goto is not None
                self.state.append(goto.action)
                continue

            if type(element) is Shift:
                # if whitespace continue
                if la.lookup in ws_tokens:
                    self.state.append(element.action)
                    self.abs_parse_distance += len(la.symbol.name)
                    parsed_distance += len(la.symbol.name)
                    la = la.next_term
                    continue
                self.state.append(element.action)
                self.abs_parse_distance += len(la.symbol.name)
                parsed_tokens += 1
                parsed_distance += len(la.symbol.name)
                if parsed_tokens >= maxtoks and parsed_distance >= maxdist:
                    return True
                la = la.next_term
                continue

            if type(element) is Accept:
                return True
            if parsed_tokens > 0:
                return True
            return False
    def parse_after(self, la, split=None, distance=1):
        """Checks if la can be parsed in the current state. If la is whitespace,
        continue until we can parse the next non-whitespace token."""
        parsed_tokens = 0
        if split:
            token = self.lexer.lex(la.prev_term.symbol.name[split:])
            tmpla = la
            la = TextNode(Terminal(token[0][1]))
            la.next_term = tmpla
        while True:
            lookup = get_lookup(la)
            element = self.syntaxtable.lookup(self.state[-1], lookup)

            if type(element) is Reduce:
                for i in range(element.amount()):
                    self.state.pop()
                goto = self.syntaxtable.lookup(self.state[-1],
                                               element.action.left)
                assert goto is not None
                self.state.append(goto.action)
                continue

            if type(element) is Shift:
                # if whitespace continue
                if la.lookup in ws_tokens:
                    self.state.append(element.action)
                    self.abs_parse_distance += len(la.symbol.name)
                    la = la.next_term
                    continue
                self.state.append(element.action)
                self.abs_parse_distance += len(la.symbol.name)
                parsed_tokens += 1
                if parsed_tokens == distance:
                    return True
                la = la.next_term
                continue

            if type(element) is Accept:
                return True
            if parsed_tokens > 0:
                return True
            return False
Esempio n. 4
0
 def parse_after_lbox_h1(self,
                         lbox,
                         end,
                         cut,
                         errornode=None,
                         split=None,
                         distance=1):
     self.abs_parse_distance = 0
     parsed_tokens = 0
     # copy stack
     stack = []
     for i in range(cut + 1):
         stack.append(self.op.stack[i].state)
         self.abs_parse_distance += self.op.stack[i].textlength()
     after_end = end.next_term
     # do all reductions until there's a shift or accept (whitespace doesn't
     # count)
     lboxnode = TextNode(lbox)
     la = lboxnode
     if split:
         token = self.ol.lex(end.symbol.name[split:])
         splitla = TextNode(Terminal(token[0][1]))
         splitla.next_term = after_end
         la.next_term = splitla
     else:
         la.next_term = after_end
     while True:
         if la.deleted:
             la = la.next_term
             continue
         element = self.op.syntaxtable.lookup(stack[-1],
                                              self.op.get_lookup(la))
         if type(element) is Reduce:
             for i in range(element.amount()):
                 stack.pop()
             goto = self.op.syntaxtable.lookup(stack[-1],
                                               element.action.left)
             assert goto is not None
             stack.append(goto.action)
             continue
         if type(element) is Shift:
             if errornode and la is errornode:
                 return True
             # if whitespace continue
             if la.lookup in ws_tokens or la is lboxnode:
                 stack.append(element.action)
                 if la is not lboxnode:
                     self.abs_parse_distance += len(la.symbol.name)
                 la = la.next_term
                 continue
             if not errornode:
                 stack.append(element.action)
                 self.abs_parse_distance += len(la.symbol.name)
                 parsed_tokens += 1
                 if parsed_tokens == distance:
                     return True
                 la = la.next_term
                 continue
         if type(element) is Accept:
             return True
         if parsed_tokens > 0:
             return True
         return False