| @@ -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]) | ||||