@@ -66,7 +66,7 @@ class UnexpectedCharacters(LexError, UnexpectedInput): | |||
if allowed: | |||
message += '\nExpecting: %s\n' % allowed | |||
super(UnexpectedCharacters, self).__init__(message.encode('utf-8')) | |||
super(UnexpectedCharacters, self).__init__(message) | |||
@@ -84,7 +84,7 @@ class UnexpectedToken(ParseError, UnexpectedInput): | |||
"Expected one of: \n\t* %s\n" | |||
% (token, self.line, self.column, '\n\t* '.join(self.expected))) | |||
super(UnexpectedToken, self).__init__(message.encode('utf-8')) | |||
super(UnexpectedToken, self).__init__(message) | |||
class VisitError(Exception): | |||
pass | |||
@@ -42,12 +42,8 @@ class LarkOptions(object): | |||
cache_grammar - Cache the Lark grammar (Default: False) | |||
postlex - Lexer post-processing (Default: None) Only works with the standard and contextual lexers. | |||
start - The start symbol (Default: start) | |||
<<<<<<< HEAD | |||
profile - Measure run-time usage in Lark. Read results from the profiler proprety (Default: False) | |||
priority - How priorities should be evaluated - auto, none, normal, invert (Default: auto) | |||
======= | |||
profile - Measure run-time usage in Lark. Read results from the profiler property (Default: False) | |||
>>>>>>> master | |||
propagate_positions - Propagates [line, column, end_line, end_column] attributes into all tree branches. | |||
lexer_callbacks - Dictionary of callbacks for the lexer. May alter tokens during lexing. Use with caution. | |||
maybe_placeholders - Experimental feature. Instead of omitting optional rules (i.e. rule?), replace them with None | |||
@@ -76,9 +72,9 @@ class LarkOptions(object): | |||
assert self.parser in ('earley', 'lalr', 'cyk', None) | |||
if self.ambiguity == 'explicit' and self.transformer: | |||
raise ValueError('Cannot specify an embedded transformer when using the Earley algorithm for explicit ambiguity.' | |||
'Please use your transformer on the resulting Forest, or use a different algorithm (i.e. LALR)') | |||
if self.parser == 'earley' and self.transformer: | |||
raise ValueError('Cannot specify an embedded transformer when using the Earley algorithm.' | |||
'Please use your transformer on the resulting parse tree, or use a different algorithm (i.e. LALR)') | |||
if o: | |||
raise ValueError("Unknown options: %s" % o.keys()) | |||
@@ -160,14 +156,16 @@ class Lark: | |||
disambig_parsers = ['earley', 'cyk'] | |||
assert self.options.parser in disambig_parsers, ( | |||
'Only %s supports disambiguation right now') % ', '.join(disambig_parsers) | |||
assert self.options.priority in ('auto', 'none', 'normal', 'invert'), 'invalid priority option specified: {}. options are auto, none, normal, invert.'.format(self.options.priority) | |||
if self.options.priority == 'auto': | |||
if self.options.parser in ('earley', 'cyk', ): | |||
self.options.priority = 'normal' | |||
elif self.options.parser in ('lalr', ): | |||
self.options.priority = 'none' | |||
if self.options.priority in ('invert', 'normal'): | |||
self.options.priority = None | |||
elif self.options.priority in ('invert', 'normal'): | |||
assert self.options.parser in ('earley', 'cyk'), "priorities are not supported for LALR at this time" | |||
assert self.options.priority in ('auto', None, 'normal', 'invert'), 'invalid priority option specified: {}. options are auto, none, normal, invert.'.format(self.options.priority) | |||
assert self.options.ambiguity not in ('resolve__antiscore_sum', ), 'resolve__antiscore_sum has been replaced with the option priority="invert"' | |||
assert self.options.ambiguity in ('resolve', 'explicit', 'auto', ) | |||
@@ -186,7 +184,7 @@ class Lark: | |||
# Else, if the user asked to disable priorities, strip them from the | |||
# rules. This allows the Earley parsers to skip an extra forest walk | |||
# for improved performance, if you don't need them (or didn't specify any). | |||
elif self.options.priority == 'none': | |||
elif self.options.priority == None: | |||
for rule in self.rules: | |||
if rule.options and rule.options.priority is not None: | |||
rule.options.priority = None | |||
@@ -100,17 +100,10 @@ class Reconstructor: | |||
for origin, rule_aliases in aliases.items(): | |||
for alias in rule_aliases: | |||
<<<<<<< HEAD | |||
yield Rule(origin, [Terminal(alias)], alias=MakeMatchTree(origin.name, [NonTerminal(alias)])) | |||
yield Rule(origin, [Terminal(origin.name)], alias=MakeMatchTree(origin.name, [origin])) | |||
======= | |||
yield Rule(origin, [Terminal(alias)], MakeMatchTree(origin.name, [NonTerminal(alias)])) | |||
yield Rule(origin, [Terminal(origin.name)], MakeMatchTree(origin.name, [origin])) | |||
>>>>>>> master | |||
def _match(self, term, token): | |||
@@ -49,6 +49,7 @@ class TestParsers(unittest.TestCase): | |||
self.assertRaises(GrammarError, Lark, g, parser='lalr') | |||
# TODO: should it? shouldn't it? | |||
# l = Lark(g, parser='earley', lexer='dynamic') | |||
# self.assertRaises(ParseError, l.parse, 'a') | |||
@@ -192,8 +193,10 @@ def _make_full_earley_test(LEXER): | |||
@unittest.skipIf(LEXER=='dynamic', "Only relevant for the dynamic_complete parser") | |||
def test_earley3(self): | |||
"Tests prioritization and disambiguation for pseudo-terminals (there should be only one result)" | |||
"""Tests prioritization and disambiguation for pseudo-terminals (there should be only one result) | |||
By default, `+` should immitate regexp greedy-matching | |||
""" | |||
grammar = """ | |||
start: A A | |||
A: "a"+ | |||
@@ -201,7 +204,7 @@ def _make_full_earley_test(LEXER): | |||
l = Lark(grammar, parser='earley', lexer=LEXER) | |||
res = l.parse("aaa") | |||
self.assertEqual(res.children, ['a', 'aa']) | |||
self.assertEqual(res.children, ['aa', 'a']) | |||
def test_earley4(self): | |||
grammar = """ | |||
@@ -211,7 +214,6 @@ def _make_full_earley_test(LEXER): | |||
l = Lark(grammar, parser='earley', lexer=LEXER) | |||
res = l.parse("aaa") | |||
# print(res.pretty()) | |||
self.assertEqual(res.children, ['aaa']) | |||
def test_earley_repeating_empty(self): | |||
@@ -242,7 +244,6 @@ def _make_full_earley_test(LEXER): | |||
parser = Lark(grammar, parser='earley', lexer=LEXER, ambiguity='explicit') | |||
ambig_tree = parser.parse('ab') | |||
# print(ambig_tree.pretty()) | |||
self.assertEqual( ambig_tree.data, '_ambig') | |||
self.assertEqual( len(ambig_tree.children), 2) | |||
@@ -258,8 +259,6 @@ def _make_full_earley_test(LEXER): | |||
""" | |||
l = Lark(grammar, parser='earley', ambiguity='explicit', lexer=LEXER) | |||
ambig_tree = l.parse('cde') | |||
# print(ambig_tree.pretty()) | |||
# tree = ApplyCallbacks(l.parser.parser.postprocess).transform(ambig_tree) | |||
assert ambig_tree.data == '_ambig', ambig_tree | |||
assert len(ambig_tree.children) == 2 | |||
@@ -304,7 +303,6 @@ def _make_full_earley_test(LEXER): | |||
""" | |||
parser = Lark(grammar, ambiguity='explicit', lexer=LEXER) | |||
tree = parser.parse('fruit flies like bananas') | |||
# tree = ApplyCallbacks(parser.parser.parser.postprocess).transform(ambig_tree) | |||
expected = Tree('_ambig', [ | |||
Tree('comparative', [ | |||
@@ -319,9 +317,6 @@ def _make_full_earley_test(LEXER): | |||
]) | |||
]) | |||
# print res.pretty() | |||
# print expected.pretty() | |||
# self.assertEqual(tree, expected) | |||
self.assertEqual(tree.data, expected.data) | |||
self.assertEqual(set(tree.children), set(expected.children)) | |||
@@ -338,7 +333,6 @@ def _make_full_earley_test(LEXER): | |||
parser = _Lark(grammar, start='start', ambiguity='explicit') | |||
tree = parser.parse(text) | |||
# print(tree.pretty()) | |||
self.assertEqual(tree.data, '_ambig') | |||
combinations = {tuple(str(s) for s in t.children) for t in tree.children} | |||
@@ -1085,7 +1079,6 @@ def _make_parser_test(LEXER, PARSER): | |||
l = Lark(grammar, priority="invert") | |||
res = l.parse('abba') | |||
# print(res.pretty()) | |||
self.assertEqual(''.join(child.data for child in res.children), 'indirection') | |||
grammar = """ | |||