@@ -63,6 +63,7 @@ Lark has no dependencies. | |||||
- Automatic token collision resolution (unless both tokens are regexps) | - Automatic token collision resolution (unless both tokens are regexps) | ||||
- Python 2 & 3 compatible | - Python 2 & 3 compatible | ||||
- Unicode fully supported | - Unicode fully supported | ||||
- Extensive test suite | |||||
## Coming soon | ## Coming soon | ||||
@@ -18,7 +18,7 @@ class Indenter: | |||||
if indent > self.indent_level[-1]: | if indent > self.indent_level[-1]: | ||||
self.indent_level.append(indent) | self.indent_level.append(indent) | ||||
yield Token(self.INDENT_type, indent_str) | |||||
yield Token.new_borrow_pos(self.INDENT_type, indent_str, token) | |||||
else: | else: | ||||
while indent < self.indent_level[-1]: | while indent < self.indent_level[-1]: | ||||
self.indent_level.pop() | self.indent_level.pop() | ||||
@@ -252,8 +252,8 @@ class ExtractAnonTokens(InlineTransformer): | |||||
try: | try: | ||||
token_name = _TOKEN_NAMES[value] | token_name = _TOKEN_NAMES[value] | ||||
except KeyError: | except KeyError: | ||||
if value.isalnum() and value[0].isalpha(): | |||||
token_name = value.upper() | |||||
if value.isalnum() and value[0].isalpha() and ('__'+value.upper()) not in self.token_set: | |||||
token_name = value.upper() # This can create name duplications for unidentical tokens | |||||
else: | else: | ||||
token_name = 'ANONSTR_%d' % self.i | token_name = 'ANONSTR_%d' % self.i | ||||
self.i += 1 | self.i += 1 | ||||
@@ -48,7 +48,7 @@ class ParseTreeBuilder: | |||||
new_rules = [] | new_rules = [] | ||||
for origin, expansions in rules.items(): | for origin, expansions in rules.items(): | ||||
expand1 = origin.startswith('?') | expand1 = origin.startswith('?') | ||||
_origin = origin.lstrip('?*') | |||||
_origin = origin.lstrip('?') | |||||
for expansion, alias in expansions: | for expansion, alias in expansions: | ||||
if alias and origin.startswith('_'): | if alias and origin.startswith('_'): | ||||
@@ -340,6 +340,17 @@ def _make_parser_test(PARSER): | |||||
g = _Lark("""start: %s | g = _Lark("""start: %s | ||||
%s""" % (' '.join(tokens), '\n'.join("%s: %s"%x for x in tokens.items()))) | %s""" % (' '.join(tokens), '\n'.join("%s: %s"%x for x in tokens.items()))) | ||||
def test_float_without_lexer(self): | |||||
g = _Lark("""start: ["+"|"-"] float | |||||
float: digit* "." digit+ exp? | |||||
| digit+ exp | |||||
exp: ("e"|"E") ["+"|"-"] digit+ | |||||
digit: "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" | |||||
""") | |||||
g.parse("1.2") | |||||
g.parse("-.2e9") | |||||
g.parse("+2e-9") | |||||
self.assertRaises(ParseError, g.parse, "+2e-9e") | |||||
_NAME = "Test" + PARSER.capitalize() | _NAME = "Test" + PARSER.capitalize() | ||||
_TestParser.__name__ = _NAME | _TestParser.__name__ = _NAME | ||||