OILS / osh / arith_parse_gen.py View on Github | oilshell.org

99 lines, 58 significant
1#!/usr/bin/env python2
2from __future__ import print_function
3
4import collections
5import sys
6
7from osh import arith_parse
8from mycpp.mylib import log
9
10_ = log
11
12
13def main(argv):
14 spec = arith_parse.Spec()
15
16 print("""\
17#include "cpp/osh.h"
18
19using syntax_asdl::arith_expr_t;
20using syntax_asdl::word_t;
21using tdop::TdopParser;
22""")
23
24 to_declare = collections.defaultdict(set)
25
26 for row in spec.nud_lookup.itervalues():
27 mod_name, func_name = row.ModuleAndFuncName()
28 to_declare[mod_name].add(('N', func_name))
29
30 # TODO: namespace are arith_parse or tdop
31 for row in spec.led_lookup.itervalues():
32 mod_name, func_name = row.ModuleAndFuncName()
33 to_declare[mod_name].add(('L', func_name))
34
35 # main program has no headers, so here are prototypes
36 for mod_name in to_declare:
37 print('namespace %s { ' % mod_name)
38 for typ, func in sorted(to_declare[mod_name]):
39 if typ == 'N':
40 # tdop::NullFunc
41 fmt = 'arith_expr_t* %s(TdopParser*, word_t*, int);'
42 else:
43 # tdop::LeftFunc
44 fmt = 'arith_expr_t* %s(TdopParser*, word_t*, arith_expr_t*, int);'
45 print(fmt % func)
46
47 print('}')
48 print('')
49
50 print("""\
51namespace arith_parse {
52
53tdop::LeftInfo kLeftLookup[] = {
54 { nullptr, 0, 0 }, // empty
55""",
56 end='')
57
58 n = max(spec.led_lookup)
59 m = max(spec.nud_lookup)
60 assert n == m
61 #log('arith_parse_gen.py: precedence table has %d entries', n)
62
63 for i in xrange(1, n):
64 row = spec.led_lookup.get(i)
65 if row is None:
66 assert False, 'No empty rows anymore'
67 print(' { nullptr, 0, 0 }, // empty')
68 else:
69 print(' %s' % row)
70
71 print("""\
72};
73
74tdop::NullInfo kNullLookup[] = {
75 { nullptr, 0 }, // empty
76""",
77 end='')
78
79 for i in xrange(1, n):
80 row = spec.nud_lookup.get(i)
81 if row is None:
82 assert False, 'No empty rows anymore'
83 print(' { nullptr, 0 }, // empty')
84 else:
85 print(' %s' % row)
86
87 print("""\
88};
89
90};
91""")
92
93
94if __name__ == '__main__':
95 try:
96 main(sys.argv)
97 except RuntimeError as e:
98 print('FATAL: %s' % e, file=sys.stderr)
99 sys.exit(1)