@@ -2,6 +2,10 @@ | |||||
class GrammarError(Exception): | class GrammarError(Exception): | ||||
pass | pass | ||||
class ParseError(Exception): | |||||
pass | |||||
def is_terminal(sym): | def is_terminal(sym): | ||||
return sym.isupper() or sym[0] == '$' | return sym.isupper() or sym[0] == '$' | ||||
@@ -1,4 +1,4 @@ | |||||
from .grammar_analysis import is_terminal | |||||
from .common import is_terminal | |||||
class Callback(object): | class Callback(object): | ||||
pass | pass | ||||
@@ -1,12 +1,12 @@ | |||||
from .grammar_analysis import GrammarAnalyzer | |||||
from .parsers.lalr_analysis import GrammarAnalyzer | |||||
from .common import is_terminal | from .common import is_terminal | ||||
from . import parser, earley | |||||
from .parsers import lalr_parser, earley | |||||
class LALR: | class LALR: | ||||
def build_parser(self, rules, callback, start): | def build_parser(self, rules, callback, start): | ||||
ga = GrammarAnalyzer(rules, start) | ga = GrammarAnalyzer(rules, start) | ||||
ga.analyze() | ga.analyze() | ||||
return parser.Parser(ga, callback) | |||||
return lalr_parser.Parser(ga, callback) | |||||
class Earley: | class Earley: | ||||
@staticmethod | @staticmethod | ||||
@@ -1,6 +1,7 @@ | |||||
"My name is Earley" | "My name is Earley" | ||||
from .utils import classify, STRING_TYPE | |||||
from ..utils import classify, STRING_TYPE | |||||
from ..common import ParseError | |||||
try: | try: | ||||
xrange | xrange | ||||
@@ -135,7 +136,7 @@ class Parser(object): | |||||
self.advance_to(table, pos + 1, set()) | self.advance_to(table, pos + 1, set()) | ||||
if not table[-1]: | if not table[-1]: | ||||
raise Exception('Error at line {t.line}:{t.column}'.format(t=stream[pos])) | |||||
raise ParseError('Error at line {t.line}:{t.column}'.format(t=stream[pos])) | |||||
return list(self.finish(table)) | return list(self.finish(table)) | ||||
@@ -1,7 +1,7 @@ | |||||
from collections import defaultdict, deque | from collections import defaultdict, deque | ||||
from .utils import classify, classify_bool, bfs, fzset | |||||
from .common import GrammarError, is_terminal | |||||
from ..utils import classify, classify_bool, bfs, fzset | |||||
from ..common import GrammarError, is_terminal | |||||
ACTION_SHIFT = 0 | ACTION_SHIFT = 0 | ||||
@@ -1,7 +1,5 @@ | |||||
from .grammar_analysis import ACTION_SHIFT | |||||
class ParseError(Exception): | |||||
pass | |||||
from .lalr_analysis import ACTION_SHIFT | |||||
from ..common import ParseError | |||||
class Parser(object): | class Parser(object): | ||||
def __init__(self, ga, callback): | def __init__(self, ga, callback): |
@@ -17,8 +17,7 @@ from io import ( | |||||
logging.basicConfig(level=logging.INFO) | logging.basicConfig(level=logging.INFO) | ||||
from lark.lark import Lark | from lark.lark import Lark | ||||
from lark.grammar_analysis import GrammarError | |||||
from lark.parser import ParseError | |||||
from lark.common import GrammarError, ParseError | |||||
__path__ = os.path.dirname(__file__) | __path__ = os.path.dirname(__file__) | ||||
def _read(n, *args): | def _read(n, *args): | ||||
@@ -33,6 +33,8 @@ class Tree(object): | |||||
def __eq__(self, other): | def __eq__(self, other): | ||||
return self.data == other.data and self.children == other.children | return self.data == other.data and self.children == other.children | ||||
def __hash__(self): | |||||
return hash((self.data, tuple(self.children))) | |||||
def find_pred(self, pred): | def find_pred(self, pred): | ||||
if pred(self): | if pred(self): | ||||
@@ -46,26 +48,6 @@ class Tree(object): | |||||
def find_data(self, data): | def find_data(self, data): | ||||
return self.find_pred(lambda t: t.data == data) | return self.find_pred(lambda t: t.data == data) | ||||
# def find_path(self, pred): | |||||
# if pred(self): | |||||
# yield [] | |||||
# else: | |||||
# for i, c in enumerate(self.children): | |||||
# if isinstance(c, Tree): | |||||
# for path in c.find_path(pred): | |||||
# yield [i] + path | |||||
# def follow_path(self, path): | |||||
# x = self | |||||
# for step in path: | |||||
# x = x.children[step] | |||||
# return x | |||||
# def set_at_path(self, path, value): | |||||
# x = self.follow_path(path[:-1]) | |||||
# x.children[path[-1]] = value | |||||
# def clone(self): | # def clone(self): | ||||
# return Tree(self.data, [c.clone() if isinstance(c, Tree) else c for c in self.children]) | # return Tree(self.data, [c.clone() if isinstance(c, Tree) else c for c in self.children]) | ||||