OILS / mycpp / examples / pgen2_demo.py View on Github | oilshell.org

106 lines, 61 significant
1#!/usr/bin/env python2
2"""
3pgen2_demo.py
4"""
5from __future__ import print_function
6
7import os
8import sys
9
10from _devbuild.gen import arith_nt
11from _devbuild.gen.syntax_asdl import source__Stdin
12
13from core import alloc
14from core import error
15from frontend import reader
16from frontend import lexer
17from oil_lang import expr_parse
18from oil_lang import expr_to_ast
19
20from mycpp import mylib
21from mycpp.mylib import log
22
23from typing import Dict, Optional, TYPE_CHECKING
24if TYPE_CHECKING:
25 from pgen2.grammar import Grammar
26 from frontend.parse_lib import ParseContext
27
28
29def ParseDemo(oil_grammar):
30 # type: (Grammar) -> None
31
32 arena = alloc.Arena()
33 arena.PushSource(source__Stdin(''))
34
35 parse_ctx = None # type: ParseContext
36 e_parser = expr_parse.ExprParser(parse_ctx, oil_grammar, False)
37
38 line_lexer = lexer.LineLexer('', arena)
39 line_reader = reader.StringLineReader('1 + 2*3', arena)
40 lex = lexer.Lexer(line_lexer, line_reader)
41
42 try:
43 pnode, _ = e_parser.Parse(lex, arith_nt.arith_expr)
44 except error.Parse as e:
45 #ui.PrettyPrintError(e, arena)
46 log("Parse Error (TODO: print it)")
47 return
48
49 # TODO: Fill this in. Oil uses parse_lib.MakeGrammarNames()
50 #
51 # terminals: _Id_str? Doesn't work in mycpp
52 # nonterminals: gr.number2symbol. Is this ever used at runtime?
53 #
54 # Dict[int,str] should really be a List[str] then?
55
56 if 0:
57 names = {} # type: Dict[int, str]
58 printer = expr_parse.ParseTreePrinter(names)
59 printer.Print(pnode)
60 # NOTE: Could also transform
61
62 # This only works for Oil
63 if 0:
64 tr = expr_to_ast.Transformer(oil_grammar)
65 node = tr.Expr(pnode)
66
67 assert node is not None
68
69 tree = node.AbbreviatedTree()
70 fmt.PrintTree(tree, mylib.Stdout())
71
72
73def run_tests():
74 # type: () -> None
75
76 if mylib.CPP:
77 # TODO: Initialize this
78 gr = None # type: Optional[Grammar]
79 else:
80 # And then cppgen_pass.py gets rid of all the "else" blocks
81
82 from pgen2 import grammar
83
84 # We're finding a bad os.pyi ?
85 repo_root = os.environ['HOME'] + '/git/oilshell/oil' # type: ignore
86 gr = grammar.Grammar()
87 f = open(repo_root + '/_devbuild/gen/arith.marshal')
88 contents = f.read()
89 gr.loads(contents)
90 f.close()
91
92 ParseDemo(gr)
93 print('done')
94
95
96def run_benchmarks():
97 # type: () -> None
98 pass
99
100
101if __name__ == '__main__':
102 if os.getenv('BENCHMARK'):
103 log('Benchmarking...')
104 run_benchmarks()
105 else:
106 run_tests()