Last active
December 20, 2017 13:18
-
-
Save taotao54321/5ac3f9b3c138b0a978aaedc63152d4fb to your computer and use it in GitHub Desktop.
tatsu calc example bug?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from __future__ import absolute_import, division, print_function, unicode_literals | |
import json | |
from codecs import open | |
from pprint import pprint | |
import tatsu | |
from tatsu.ast import AST | |
from tatsu.walkers import NodeWalker | |
from codegen import PostfixCodeGenerator | |
def simple_parse(): | |
grammar = open('grammars/calc_cut.ebnf').read() | |
parser = tatsu.compile(grammar) | |
#ast = parser.parse('3 + 5 * ( 10 - 20 )', trace=False, colorize=True) | |
ast = parser.parse('1 * 2 + 3 - 4', trace=False, colorize=True) | |
print() | |
print('# SIMPLE PARSE') | |
print('# AST') | |
pprint(ast, width=20, indent=4) | |
print() | |
print('# JSON') | |
print(json.dumps(ast, indent=4)) | |
print() | |
def annotated_parse(): | |
grammar = open('grammars/calc_annotated.ebnf').read() | |
parser = tatsu.compile(grammar) | |
#ast = parser.parse('3 + 5 * ( 10 - 20 )') | |
ast = parser.parse('1 * 2 + 3 - 4') | |
print() | |
print('# ANNOTATED AST') | |
pprint(ast, width=20, indent=4) | |
print() | |
class CalcBasicSemantics(object): | |
def number(self, ast): | |
return int(ast) | |
def term(self, ast): | |
if not isinstance(ast, AST): | |
return ast | |
elif ast.op == '*': | |
return ast.left * ast.right | |
elif ast.op == '/': | |
return ast.left / ast.right | |
else: | |
raise Exception('Unknown operator', ast.op) | |
def expression(self, ast): | |
if not isinstance(ast, AST): | |
return ast | |
elif ast.op == '+': | |
return ast.left + ast.right | |
elif ast.op == '-': | |
return ast.left - ast.right | |
else: | |
raise Exception('Unknown operator', ast.op) | |
def parse_with_basic_semantics(): | |
grammar = open('grammars/calc_annotated.ebnf').read() | |
parser = tatsu.compile(grammar) | |
result = parser.parse( | |
#'3 + 5 * ( 10 - 20 )', | |
'1 * 2 + 3 - 4', | |
semantics=CalcBasicSemantics() | |
) | |
print() | |
print('# BASIC SEMANTICS RESULT') | |
#assert result == -47 | |
assert result == 1 | |
print(result) | |
print() | |
class CalcSemantics(object): | |
def number(self, ast): | |
return int(ast) | |
def addition(self, ast): | |
return ast.left + ast.right | |
def subtraction(self, ast): | |
return ast.left - ast.right | |
def multiplication(self, ast): | |
return ast.left * ast.right | |
def division(self, ast): | |
return ast.left / ast.right | |
def parse_factored(): | |
grammar = open('grammars/calc_factored.ebnf').read() | |
parser = tatsu.compile(grammar) | |
ast = parser.parse( | |
#'3 + 5 * ( 10 - 20 )', | |
'1 * 2 + 3 - 4', | |
semantics=CalcSemantics() | |
) | |
print() | |
print('# FACTORED SEMANTICS RESULT') | |
pprint(ast, width=20, indent=4) | |
print() | |
def parse_to_model(): | |
grammar = open('grammars/calc_model.ebnf').read() | |
parser = tatsu.compile(grammar, asmodel=True) | |
#model = parser.parse('3 + 5 * ( 10 - 20 )') | |
model = parser.parse('1 * 2 + 3 - 4') | |
print() | |
print('# MODEL TYPE IS:', type(model).__name__) | |
print(json.dumps(model.asjson(), indent=4)) | |
print() | |
class CalcWalker(NodeWalker): | |
def walk_object(self, node): | |
return node | |
def walk__add(self, node): | |
return self.walk(node.left) + self.walk(node.right) | |
def walk__subtract(self, node): | |
return self.walk(node.left) - self.walk(node.right) | |
def walk__multiply(self, node): | |
return self.walk(node.left) * self.walk(node.right) | |
def walk__divide(self, node): | |
return self.walk(node.left) / self.walk(node.right) | |
def parse_and_walk_model(): | |
grammar = open('grammars/calc_model.ebnf').read() | |
parser = tatsu.compile(grammar, asmodel=True) | |
#model = parser.parse('3 + 5 * ( 10 - 20 )') | |
model = parser.parse('1 * 2 + 3 - 4') | |
print() | |
print('# WALKER RESULT') | |
result = CalcWalker().walk(model) | |
assert result == -47 | |
print(result) | |
print() | |
def parse_and_translate(): | |
grammar = open('grammars/calc_model.ebnf').read() | |
parser = tatsu.compile(grammar, asmodel=True) | |
#model = parser.parse('3 + 5 * ( 10 - 20 )') | |
model = parser.parse('1 * 2 + 3 - 4') | |
postfix = PostfixCodeGenerator().render(model) | |
print() | |
print('# TRANSLATED TO POSTFIX') | |
print(postfix) | |
def main(): | |
simple_parse() | |
annotated_parse() | |
parse_with_basic_semantics() | |
parse_factored() | |
parse_to_model() | |
parse_and_walk_model() | |
parse_and_translate() | |
if __name__ == '__main__': | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Traceback (most recent call last): | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/contexts.py", line 203, in parse | |
result = rule() | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 693, in parse | |
result = self._parse_rhs(ctx, self.exp) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 700, in _parse_rhs | |
result = ctx._call(ruleinfo) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/contexts.py", line 509, in _call | |
result = self._recursive_call(ruleinfo) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/contexts.py", line 540, in _recursive_call | |
result = self._invoke_rule(ruleinfo, key) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/contexts.py", line 573, in _invoke_rule | |
ruleinfo.impl(self) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 348, in parse | |
ctx.last_node = [s.parse(ctx) for s in self.sequence] | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 348, in <listcomp> | |
ctx.last_node = [s.parse(ctx) for s in self.sequence] | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 203, in parse | |
ctx._check_eof() | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/contexts.py", line 642, in _check_eof | |
self._error('Expecting end of text', exclass=FailedExpectingEndOfText) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/contexts.py", line 435, in _error | |
raise self._make_exception(item, exclass=exclass) | |
tatsu.exceptions.FailedExpectingEndOfText: (1:11) Expecting end of text : | |
1 * 2 + 3 - 4 | |
^ | |
start | |
During handling of the above exception, another exception occurred: | |
Traceback (most recent call last): | |
File "calc.py", line 192, in <module> | |
main() | |
File "calc.py", line 185, in main | |
parse_factored() | |
File "calc.py", line 113, in parse_factored | |
semantics=CalcSemantics() | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 945, in parse | |
**kwargs | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/contexts.py", line 211, in parse | |
raise self._furthest_exception | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/contexts.py", line 672, in _option | |
yield | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 394, in parse | |
ctx.last_node = o.parse(ctx) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 649, in parse | |
return rule() | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 693, in parse | |
result = self._parse_rhs(ctx, self.exp) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 700, in _parse_rhs | |
result = ctx._call(ruleinfo) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/contexts.py", line 509, in _call | |
result = self._recursive_call(ruleinfo) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/contexts.py", line 540, in _recursive_call | |
result = self._invoke_rule(ruleinfo, key) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/contexts.py", line 573, in _invoke_rule | |
ruleinfo.impl(self) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 348, in parse | |
ctx.last_node = [s.parse(ctx) for s in self.sequence] | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 348, in <listcomp> | |
ctx.last_node = [s.parse(ctx) for s in self.sequence] | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 586, in parse | |
value = self.exp.parse(ctx) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/grammars.py", line 266, in parse | |
return ctx._token(self.token) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/contexts.py", line 610, in _token | |
self._error(token, exclass=FailedToken) | |
File "/home/lain/.local/lib/python3.6/site-packages/tatsu/contexts.py", line 435, in _error | |
raise self._make_exception(item, exclass=exclass) | |
tatsu.exceptions.FailedToken: (1:11) expecting '*' : | |
1 * 2 + 3 - 4 | |
^ | |
multiplication | |
term | |
addition | |
expression | |
start |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment