Commits

Alex Gaynor committed 339a4d4

Working parser!

Comments (0)

Files changed (3)

minijs/grammar.txt

+FLOAT: "[0-9]+";
+main: statement* [EOF];
+
+statement: expr ";";
+
+expr: comparison;
+
+comparison: primary;
+primary: atom;
+atom: FLOAT;
 import os
 
-from pypy.rlib.parsing.ebnfparse import parse_ebnf
+from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function
 
 
-grammar = os.path.join(os.path.dirname(__file__), "grammar.txt")
+with open(os.path.join(os.path.dirname(__file__), "grammar.txt")) as f:
+    grammar = f.read()
 regexs, rules, _ = parse_ebnf(grammar)
 _parse = make_parse_function(regexs, rules, eof=True)
 
 
 
 class Transformer(object):
-    pass
+    def visit_main(self, node):
+        return self.visit_block(node.children[0])
+
+    def visit_block(self, node):
+        stmts = []
+        while True:
+            stmts.append(self.visit_stmt(node.children[0]))
+            if len(node.children) == 1:
+                break
+            node = node.children[1]
+        return Block(stmts)
+
+    def visit_stmt(self, node):
+        if node.children[0].symbol == "expr":
+            return Stmt(self.visit_expr(node.children[0]))
+        raise NotImplementedError
+
+    def visit_expr(self, node):
+        if node.symbol == "expr":
+            node = node.children[0]
+        if node.symbol == "comparison":
+            return self.visit_subexpr(node)
+        elif node.symbol == "primary":
+            return self.visit_primary(node)
+        raise NotImplementedError
+
+    def visit_subexpr(self, node):
+        if len(node.children) == 1:
+            return self.visit_expr(node.children[0])
+        raise NotImplementedError
+
+    def visit_primary(self, node):
+        if len(node.children) == 1:
+            return self.visit_atom(node.children[0])
+        raise NotImplementedError
+
+    def visit_atom(self, node):
+        if node.children[0].symbol == "FLOAT":
+            return ConstantFloat(float(node.children[0].additional_info))

tests/test_parser.py

 
 class TestParser(object):
     def test_const_float(self, space):
-        assert space.parse("1") == Block([Stmt(ConstantFloat(1))])
+        assert space.parse("1;") == Block([Stmt(ConstantFloat(1))])