diff --git a/docs/grammar.md b/docs/grammar.md index 69a6704..87912a5 100644 --- a/docs/grammar.md +++ b/docs/grammar.md @@ -43,7 +43,7 @@ Literals can be one of: * `/regular expression+/` * `"case-insensitive string"i` * `/re with flags/imulx` -* Literal range: `"a".."z"`, `"1..9"`, etc. +* Literal range: `"a".."z"`, `"1".."9"`, etc. #### Notes for when using a lexer: @@ -145,4 +145,4 @@ If the module path is relative, such as `.path.to.file`, Lark will attempt to lo ### %declare -Declare a terminal without defining it. Useful for plugins. \ No newline at end of file +Declare a terminal without defining it. Useful for plugins. diff --git a/docs/how_to_use.md b/docs/how_to_use.md index 95041e4..5113d27 100644 --- a/docs/how_to_use.md +++ b/docs/how_to_use.md @@ -52,3 +52,19 @@ class MyTransformer(Transformer): new_tree = MyTransformer().transform(tree) ``` +## LALR usage + +By default Lark silently resolves Shift/Reduce conflicts as Shift. To enable warnings pass `debug=True`. To get the messages printed you have to configure `logging` framework beforehand. For example: + +```python +from lark import Lark +import logging +logging.basicConfig(level=logging.DEBUG) + +collision_grammar = ''' +start: as as +as: a* +a: 'a' +''' +p = Lark(collision_grammar, parser='lalr', debug=True) +``` diff --git a/lark/load_grammar.py b/lark/load_grammar.py index 76c9b10..62bdfc5 100644 --- a/lark/load_grammar.py +++ b/lark/load_grammar.py @@ -526,8 +526,12 @@ def import_grammar(grammar_path, base_paths=[]): return _imported_grammars[grammar_path] def import_from_grammar_into_namespace(grammar, namespace, aliases): + """Returns all rules and terminals of grammar, prepended + with a 'namespace' prefix, except for those which are aliased. + """ + imported_terms = dict(grammar.term_defs) - imported_rules = {n:(n,t,o) for n,t,o in grammar.rule_defs} + imported_rules = {n:(n,deepcopy(t),o) for n,t,o in grammar.rule_defs} term_defs = [] rule_defs = [] @@ -535,7 +539,10 @@ def import_from_grammar_into_namespace(grammar, namespace, aliases): def rule_dependencies(symbol): if symbol.type != 'RULE': return [] - _, tree, _ = imported_rules[symbol] + try: + _, tree, _ = imported_rules[symbol] + except KeyError: + raise GrammarError("Missing symbol '%s' in grammar %s" % (symbol, namespace)) return tree.scan_values(lambda x: x.type in ('RULE', 'TERMINAL')) def get_namespace_name(name):