Skip to content

Commit

Permalink
[ASDL] Demo of arithmetic evaluator.
Browse files Browse the repository at this point in the history
I did this to test out the downcasting, which is a bit annoying.

The latest release of MyPy may help with this.
  • Loading branch information
Andy Chu committed Feb 14, 2019
1 parent 32ba76c commit 9d240f1
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 15 deletions.
11 changes: 10 additions & 1 deletion asdl/typed.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,16 @@ iter-arith() {
asdl/run.sh gen-typed-arith-asdl
check-arith

PYTHONPATH=. asdl/typed_arith_parse_test.py
export PYTHONPATH=.
asdl/typed_arith_parse_test.py

echo '---'
asdl/typed_arith_parse.py parse '40+2'
echo

echo '---'
asdl/typed_arith_parse.py eval '40+2+5'
echo
}

# --no-strict-optional issues
Expand Down
73 changes: 59 additions & 14 deletions asdl/typed_arith_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@
import sys

from _devbuild.gen import typed_arith_asdl
from _devbuild.gen.typed_arith_asdl import arith_expr_t
from _devbuild.gen.typed_arith_asdl import arith_expr__Binary
from _devbuild.gen.typed_arith_asdl import arith_expr__FuncCall
from _devbuild.gen.typed_arith_asdl import (
arith_expr, arith_expr_e, arith_expr_t,
arith_expr__Binary, arith_expr__FuncCall, arith_expr__Const)

from typing import List, Optional, Union
from typing import Dict, List, Optional, Union, cast

from asdl import tdop
from asdl.tdop import Parser
from asdl.tdop import ParserSpec

arith_expr = typed_arith_asdl.arith_expr
Token = tdop.Token


Expand Down Expand Up @@ -255,19 +254,65 @@ def ParseShell(s, expected=None):
return tree


class Evaluator(object):
def __init__(self):
# type: () -> None
self.mem = {} # type: Dict[str, int]

def Eval(self, node):
# type: (arith_expr_t) -> int

tag = node.tag
if tag == arith_expr_e.Const:
n = cast(arith_expr__Const, node)

assert n.i is not None
return n.i

if tag == arith_expr_e.Binary:
n2 = cast(arith_expr__Binary, node)

assert n2.left is not None
assert n2.right is not None

left = self.Eval(n2.left)
right = self.Eval(n2.right)
op = n2.op

if op == '+':
return left + right

return 3


def main(argv):
# type: (List[str]) -> None
# type: (List[str]) -> int
try:
s = argv[1]
action = argv[1]
s = argv[2]
except IndexError:
print('Usage: ./arith_parse.py EXPRESSION')
print('Usage: ./arith_parse.py ACTION EXPRESSION')
return 2

try:
node = ParseShell(s)
except tdop.ParseError as e:
print('Error parsing %r: %s' % (s, e), file=sys.stderr)

if action == 'parse':
print(node)
elif action == 'eval':
ev = Evaluator()
result = ev.Eval(node)
print(node)
print(' => ')
print(result)
else:
try:
tree = ParseShell(s)
except tdop.ParseError as e:
print('Error parsing %r: %s' % (s, e), file=sys.stderr)
print(tree)
print('Invalid action %r' % action)
return 2

return 0


if __name__ == '__main__':
main(sys.argv)
sys.exit(main(sys.argv))

0 comments on commit 9d240f1

Please sign in to comment.