Beispiel #1
0
 def init(self):
     bos = BOS(Terminal(""), 0, [])
     eos = EOS(FinishSymbol(), 0, [])
     bos.next_term = eos
     eos.prev_term = bos
     root = TextNode(Nonterminal("Root"), 0, [bos, eos])
     self.parent = root
Beispiel #2
0
    def __init__(self, start_symbol, grammar, lr_type=0):
        self.grammar = grammar
        self.start_symbol = start_symbol
        self.state_sets = []
        self.edges = {}
        self.ids = {}
        self.todo = []
        self.done = set()
        self.maybe_compatible = {}

        self.goto_time = 0
        self.add_time = 0
        self.closure_time = 0
        self.closure_count = 0
        self.addcount = 0
        self.weakly = 0
        self.weakly_count = 0
        self.mergetime = 0

        helper = Helper(grammar)
        self.helper = helper
        if lr_type == LR0:
            self.closure = helper.closure_0
            self.goto = helper.goto_0
            self.start_set = StateSet(
                [LR0Element(Production(None, [self.start_symbol]), 0)])
        elif lr_type == LR1 or lr_type == LALR:
            self.closure = helper.closure_1
            self.goto = helper.goto_1
            self.start_set = StateSet()
            self.start_set.add(
                LR0Element(Production(None, [self.start_symbol]), 0),
                set([FinishSymbol()]))
Beispiel #3
0
 def prepare_input(self, _input):
     l = []
     # XXX need an additional lexer to do this right
     if _input != "":
         for i in _input.split(" "):
             l.append(Terminal(i))
     l.append(FinishSymbol())
     return l
Beispiel #4
0
 def init_ast(self, magic_parent=None):
     bos = BOS(Terminal(""), 0, [])
     eos = EOS(FinishSymbol(), 0, [])
     bos.magic_parent = magic_parent
     eos.magic_parent = magic_parent
     bos.next_term = eos
     eos.prev_term = bos
     root = Node(Nonterminal("Root"), 0, [bos, eos])
     self.previous_version = AST(root)
     root.save(0)
     bos.save(0)
     eos.save(0)
Beispiel #5
0
    def check(self, _input):
        self.reset()

        l = []
        # XXX need an additional lexer to do this right
        for i in _input.split(" "):
            l.append(Terminal(i))
        l.append(FinishSymbol())
        _input = l

        self.stack.append(FinishSymbol())
        self.stack.append(0)

        i = 0
        while i < len(_input):
            c = _input[i]
            state_id = self.stack[-1]
            element = self.syntaxtable.lookup(state_id, c)
            if element is None:
                return False
            if isinstance(element, Shift):
                self.stack.append(c)
                self.stack.append(element.action)
                i += 1
            if isinstance(element, Reduce):
                for x in range(2 * element.amount()):
                    self.stack.pop()
                state_id = self.stack[-1]
                self.stack.append(element.action.left)
                element = self.syntaxtable.lookup(state_id,
                                                  element.action.left)
                assert isinstance(element, Goto)
                self.stack.append(element.action)

            if isinstance(element, Accept):
                return True
Beispiel #6
0
 def get_ast(self):
     bos = Node(Terminal("bos"), 0, [])
     eos = Node(FinishSymbol(), 0, [])
     root = Node(Nonterminal("Root"), 0, [bos, self.ast_stack[0], eos])
     return AST(root)
Beispiel #7
0
    def inc_parse(self, line_indents=[], reparse=False):
        logging.debug("============ NEW INCREMENTAL PARSE ================= ")
        self.validating = False
        self.error_node = None
        self.stack = []
        self.undo = []
        self.current_state = 0
        self.stack.append(Node(FinishSymbol(), 0, []))
        bos = self.previous_version.parent.children[0]
        self.loopcount = 0

        USE_OPT = True

        self.pm.do_incparse_inc_parse_top()

        la = self.pop_lookahead(bos)
        while (True):
            logging.debug("\x1b[35mProcessing\x1b[0m %s %s %s %s", la,
                          la.changed, id(la), la.indent)
            self.loopcount += 1
            if isinstance(la.symbol, Terminal) or isinstance(
                    la.symbol, FinishSymbol) or la.symbol == Epsilon():
                if la.changed:
                    assert False  # with prelexing you should never end up here!
                else:
                    lookup_symbol = self.get_lookup(la)
                    result = self.parse_terminal(la, lookup_symbol)
                    if result == "Accept":
                        self.last_status = True
                        return True
                    elif result == "Error":
                        self.last_status = False
                        return False
                    elif result != None:
                        la = result

            else:  # Nonterminal
                if la.changed or reparse:
                    # deconstruct the
                    #la.changed = False # as all nonterminals that have changed are being rebuild, there is no need to change this flag (this also solves problems with comments)
                    self.undo.append((la, 'changed', True))
                    la = self.left_breakdown(la)
                else:
                    if USE_OPT:
                        #Follow parsing/syntax table
                        goto = self.syntaxtable.lookup(self.current_state,
                                                       la.symbol)
                        if goto:  # can we shift this Nonterminal in the current state?
                            logging.debug("OPTShift: %s in state %s -> %s",
                                          la.symbol, self.current_state, goto)
                            self.pm.do_incparse_optshift(la)
                            follow_id = goto.action
                            self.stack.append(la)
                            la.state = follow_id  #XXX this fixed goto error (I should think about storing the states on the stack instead of inside the elements)
                            self.current_state = follow_id
                            logging.debug("USE_OPT: set state to %s",
                                          self.current_state)
                            la = self.pop_lookahead(la)
                            self.validating = True
                            continue
                        else:
                            #XXX can be made faster by providing more information in syntax tables
                            first_term = la.find_first_terminal()

                            lookup_symbol = self.get_lookup(first_term)
                            element = self.syntaxtable.lookup(
                                self.current_state, lookup_symbol)
                            if isinstance(element, Reduce):
                                self.reduce(element)
                            else:
                                la = self.left_breakdown(la)
                    else:
                        # PARSER WITHOUT OPTIMISATION
                        if la.lookup != "":
                            lookup_symbol = Terminal(la.lookup)
                        else:
                            lookup_symbol = la.symbol
                        element = self.syntaxtable.lookup(
                            self.current_state, lookup_symbol)

                        if self.shiftable(la):
                            logging.debug("\x1b[37mis shiftable\x1b[0m")
                            self.stack.append(la)
                            self.current_state = la.state
                            self.right_breakdown()
                            la = self.pop_lookahead(la)
                        else:
                            la = self.left_breakdown(la)
        logging.debug("============ INCREMENTAL PARSE END ================= ")