@@ -1,5 +1,8 @@ | |||
import re | |||
import sre_parse | |||
import sys | |||
Py36 = (sys.version_info[:2] >= (3, 6)) | |||
class GrammarError(Exception): | |||
pass | |||
@@ -54,7 +57,7 @@ class Pattern(object): | |||
self.flags = flags | |||
def __repr__(self): | |||
return repr(self._get_flags() + self.value) | |||
return repr(self.to_regexp()) | |||
# Pattern Hashing assumes all subclasses have a different priority! | |||
def __hash__(self): | |||
@@ -62,15 +65,24 @@ class Pattern(object): | |||
def __eq__(self, other): | |||
return type(self) == type(other) and self.value == other.value | |||
def _get_flags(self): | |||
if self.flags: | |||
assert len(self.flags) == 1 | |||
return '(?%s)' % self.flags | |||
return '' | |||
if Py36: | |||
# Python 3.6 changed syntax for flags in regular expression | |||
def _get_flags(self, value): | |||
if self.flags: | |||
assert len(self.flags) == 1 | |||
return ('(?%s:%s)' % (self.flags[0], value)) | |||
return value | |||
else: | |||
def _get_flags(self, value): | |||
if self.flags: | |||
assert len(self.flags) == 1 | |||
return ('(?%s)' % self.flags) + value | |||
return value | |||
class PatternStr(Pattern): | |||
def to_regexp(self): | |||
return self._get_flags() + re.escape(self.value) | |||
return self._get_flags(re.escape(self.value)) | |||
@property | |||
def min_width(self): | |||
@@ -79,7 +91,7 @@ class PatternStr(Pattern): | |||
class PatternRE(Pattern): | |||
def to_regexp(self): | |||
return self._get_flags() + self.value | |||
return self._get_flags(self.value) | |||
@property | |||
def min_width(self): | |||
@@ -30,12 +30,12 @@ def _read(n, *args): | |||
class TestParsers(unittest.TestCase): | |||
def test_same_ast(self): | |||
"Tests that Earley and LALR parsers produce equal trees" | |||
g = Lark("""start: "(" name_list ("," "*" NAME)? ")" | |||
g = Lark(r"""start: "(" name_list ("," "*" NAME)? ")" | |||
name_list: NAME | name_list "," NAME | |||
NAME: /\w+/ """, parser='lalr') | |||
l = g.parse('(a,b,c,*x)') | |||
g = Lark("""start: "(" name_list ("," "*" NAME)? ")" | |||
g = Lark(r"""start: "(" name_list ("," "*" NAME)? ")" | |||
name_list: NAME | name_list "," NAME | |||
NAME: /\w/+ """) | |||
l2 = g.parse('(a,b,c,*x)') | |||
@@ -507,7 +507,7 @@ def _make_parser_test(LEXER, PARSER): | |||
g.parse("a" * (sys.getrecursionlimit() // 4)) | |||
def test_token_collision(self): | |||
g = _Lark("""start: "Hello" NAME | |||
g = _Lark(r"""start: "Hello" NAME | |||
NAME: /\w/+ | |||
%ignore " " | |||
""") | |||
@@ -517,7 +517,7 @@ def _make_parser_test(LEXER, PARSER): | |||
self.assertSequenceEqual(x.children, ['HelloWorld']) | |||
def test_token_collision_WS(self): | |||
g = _Lark("""start: "Hello" NAME | |||
g = _Lark(r"""start: "Hello" NAME | |||
NAME: /\w/+ | |||
%import common.WS | |||
%ignore WS | |||