瀏覽代碼

LALR parser: towards generating a standalone (very far away still)

tags/gm/2021-09-23T00Z/github.com--lark-parser-lark/0.5.1
Erez Shinan 7 年之前
父節點
當前提交
9d065c9642
共有 1 個文件被更改,包括 22 次插入12 次删除
  1. +22
    -12
      lark/parsers/lalr_parser.py

+ 22
- 12
lark/parsers/lalr_parser.py 查看文件

@@ -7,31 +7,41 @@ from ..common import ParseError, UnexpectedToken

from .lalr_analysis import LALR_Analyzer, ACTION_SHIFT

class Parser(object):
class Parser:
def __init__(self, parser_conf):
assert all(o is None or o.priority is None for n,x,a,o in parser_conf.rules), "LALR doesn't yet support prioritization"
self.analysis = LALR_Analyzer(parser_conf.rules, parser_conf.start)
self.analysis.compute_lookahead()
self.callbacks = {rule: getattr(parser_conf.callback, rule.alias or rule.origin, None)
for rule in self.analysis.rules}
self.analysis = analysis = LALR_Analyzer(parser_conf.rules, parser_conf.start)
analysis.compute_lookahead()
callbacks = {rule: getattr(parser_conf.callback, rule.alias or rule.origin, None)
for rule in analysis.rules}

self.parser = _Parser(analysis.states_idx, analysis.init_state_idx, analysis.start_symbol, callbacks)
self.parse = self.parser.parse

class _Parser:
def __init__(self, states, init_state, start_symbol, callbacks):
self.states = states
self.init_state = init_state
self.start_symbol = start_symbol
self.callbacks = callbacks

def parse(self, seq, set_state=None):
i = 0
token = None
stream = iter(seq)
states_idx = self.analysis.states_idx
states = self.states

state_stack = [self.analysis.init_state_idx]
state_stack = [self.init_state]
value_stack = []

if set_state: set_state(self.analysis.init_state_idx)
if set_state: set_state(self.init_state)

def get_action(key):
state = state_stack[-1]
try:
return states_idx[state][key]
return states[state][key]
except KeyError:
expected = states_idx[state].keys()
expected = states[state].keys()

raise UnexpectedToken(token, expected, seq, i)

@@ -45,7 +55,7 @@ class Parser(object):

res = self.callbacks[rule](s)

if end and len(state_stack) == 1 and rule.origin == self.analysis.start_symbol:
if end and len(state_stack) == 1 and rule.origin == self.start_symbol:
return res

_action, new_state = get_action(rule.origin)
@@ -76,7 +86,7 @@ class Parser(object):
assert _action == 'reduce'
res = reduce(*rule, end=True)
if res:
assert state_stack == [self.analysis.init_state_idx] and not value_stack, len(state_stack)
assert state_stack == [self.init_state] and not value_stack, len(state_stack)
return res




Loading…
取消
儲存