Update Makefile to make it compile with recent pilex
[c_to_python.git] / scan-gram_to_l.py
1 #!/usr/bin/env python3
2
3 import sys
4 import xml.etree.ElementTree
5
6 def get_text(root, i):
7   if i < 0:
8     i += len(root) + 1
9   text = root.text if i == 0 else root[i - 1].tail
10   return '' if text is None else text
11
12 def set_text(root, i, text):
13   if i < 0:
14     i += len(root) + 1
15   if len(text) == 0:
16     text = None
17   if i == 0:
18     root.text = text
19   else:
20     root[i - 1].tail = text
21
22 def to_text(root):
23   return ''.join(
24     [
25       j
26       for i in range(len(root))
27       for j in [get_text(root, i), to_text(root[i])]
28     ] +
29     [get_text(root, len(root))]
30   )
31
32 root = xml.etree.ElementTree.parse(sys.stdin).getroot()[0]
33
34 def replace_in_action(i):
35   if i.tag == 'AST_Section2_Rule_Action' and len(i):
36     assert i[0].tag == 'AST_Text'
37     text = get_text(i[0], 0)
38
39     # see tests/parse-gram.y
40     text = text.replace('GRAM_EOF', 'y_tab.GRAM_EOF')
41     text = text.replace('STRING', 'y_tab.STRING')
42
43     text = text.replace('PERCENT_TOKEN', 'y_tab.PERCENT_TOKEN')
44     text = text.replace('PERCENT_NTERM', 'y_tab.PERCENT_NTERM')
45
46     text = text.replace('PERCENT_TYPE', 'y_tab.PERCENT_TYPE')
47     text = text.replace('PERCENT_DESTRUCTOR', 'y_tab.PERCENT_DESTRUCTOR')
48     text = text.replace('PERCENT_PRINTER', 'y_tab.PERCENT_PRINTER')
49
50     text = text.replace('PERCENT_LEFT', 'y_tab.PERCENT_LEFT')
51     text = text.replace('PERCENT_RIGHT', 'y_tab.PERCENT_RIGHT')
52     text = text.replace('PERCENT_NONASSOC', 'y_tab.PERCENT_NONASSOC')
53     text = text.replace('PERCENT_PRECEDENCE', 'y_tab.PERCENT_PRECEDENCE')
54
55     text = text.replace('PERCENT_PREC', 'y_tab.PERCENT_PREC')
56     text = text.replace('PERCENT_DPREC', 'y_tab.PERCENT_DPREC')
57     text = text.replace('PERCENT_MERGE', 'y_tab.PERCENT_MERGE')
58
59     text = text.replace('PERCENT_CODE', 'y_tab.PERCENT_CODE')
60     text = text.replace('PERCENT_DEFAULT_PREC', 'y_tab.PERCENT_DEFAULT_PREC')
61     text = text.replace('PERCENT_DEFINE', 'y_tab.PERCENT_DEFINE')
62     text = text.replace('PERCENT_DEFINES', 'y_tab.PERCENT_DEFINES')
63     text = text.replace('PERCENT_ERROR_VERBOSE', 'y_tab.PERCENT_ERROR_VERBOSE')
64     text = text.replace('PERCENT_EXPECT', 'y_tab.PERCENT_EXPECT')
65     text = text.replace('PERCENT_EXPECT_RR', 'y_tab.PERCENT_EXPECT_RR')
66     text = text.replace('PERCENT_FLAG', 'y_tab.PERCENT_FLAG')
67     text = text.replace('PERCENT_FILE_PREFIX', 'y_tab.PERCENT_FILE_PREFIX')
68     text = text.replace('PERCENT_GLR_PARSER', 'y_tab.PERCENT_GLR_PARSER')
69     text = text.replace('PERCENT_INITIAL_ACTION', 'y_tab.PERCENT_INITIAL_ACTION')
70     text = text.replace('PERCENT_LANGUAGE', 'y_tab.PERCENT_LANGUAGE')
71     text = text.replace('PERCENT_NAME_PREFIX', 'y_tab.PERCENT_NAME_PREFIX')
72     text = text.replace('PERCENT_NO_DEFAULT_PREC', 'y_tab.PERCENT_NO_DEFAULT_PREC')
73     text = text.replace('PERCENT_NO_LINES', 'y_tab.PERCENT_NO_LINES')
74     text = text.replace('PERCENT_NONDETERMINISTIC_PARSER', 'y_tab.PERCENT_NONDETERMINISTIC_PARSER')
75     text = text.replace('PERCENT_OUTPUT', 'y_tab.PERCENT_OUTPUT')
76     text = text.replace('PERCENT_REQUIRE', 'y_tab.PERCENT_REQUIRE')
77     text = text.replace('PERCENT_SKELETON', 'y_tab.PERCENT_SKELETON')
78     text = text.replace('PERCENT_START', 'y_tab.PERCENT_START')
79     text = text.replace('PERCENT_TOKEN_TABLE', 'y_tab.PERCENT_TOKEN_TABLE')
80     text = text.replace('PERCENT_VERBOSE', 'y_tab.PERCENT_VERBOSE')
81     text = text.replace('PERCENT_YACC', 'y_tab.PERCENT_YACC')
82
83     text = text.replace('BRACED_CODE', 'y_tab.BRACED_CODE')
84     text = text.replace('BRACED_PREDICATE', 'y_tab.BRACED_PREDICATE')
85     text = text.replace('BRACKETED_ID', 'y_tab.BRACKETED_ID')
86     text = text.replace('CHAR', 'y_tab.CHAR')
87     text = text.replace('EPILOGUE', 'y_tab.EPILOGUE')
88     text = text.replace('EQUAL', 'y_tab.EQUAL')
89     text = text.replace('ID', 'y_tab.ID')
90     text = text.replace('ID_COLON', 'y_tab.ID_COLON')
91     text = text.replace('PERCENT_PERCENT', 'y_tab.PERCENT_PERCENT')
92     text = text.replace('PIPE', 'y_tab.PIPE')
93     text = text.replace('PROLOGUE', 'y_tab.PROLOGUE')
94     text = text.replace('SEMICOLON', 'y_tab.SEMICOLON')
95     text = text.replace('TAG', 'y_tab.TAG')
96     text = text.replace('TAG_ANY', 'y_tab.TAG_ANY')
97     text = text.replace('TAG_NONE', 'y_tab.TAG_NONE')
98
99     text = text.replace('INT', 'y_tab.INT')
100
101     text = text.replace('PERCENT_PARAM', 'y_tab.PERCENT_PARAM')
102
103     text = text.replace('PERCENT_UNION', 'y_tab.PERCENT_UNION')
104
105     text = text.replace('PERCENT_EMPTY', 'y_tab.PERCENT_EMPTY')
106     text = text.replace('PERCENT_SPACE', 'y_tab.PERCENT_SPACE')
107
108     set_text(i[0], 0, text)
109   else:
110     for j in i:
111       replace_in_action(j)
112 replace_in_action(root)
113
114 text = to_text(root)
115
116 # see tests/scan-gram.l
117 text = text.replace(r'{letter}[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]', '{letter}')
118 text = text.replace(r'{letter}(?:[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_])', '{letter}')
119 text = text.replace(r'{notletter}[^.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]{-}[%\{]', '{notletter}')
120 text = text.replace(r'{notletter}(?:[^.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]{-}[%\{])', '{notletter}')
121 text = text.replace(r'{id}{letter}({letter}|[-0-9])*', '{id}')
122 text = text.replace(r'{id}(?:{letter}({letter}|[-0-9])*)', '{id}')
123 text = text.replace(r'{int}[0-9]+', '{int}')
124 text = text.replace(r'{int}(?:[0-9]+)', '{int}')
125
126 text = text.replace(r'{splice}(\\[ \f\t\v]*\n)*', '{splice}')
127 text = text.replace(r'{splice}(?:(\\[ \f\t\v]*\n)*)', '{splice}')
128
129 text = text.replace(r'{eqopt}([[:space:]]*=)?', '{eqopt}')
130 text = text.replace(r'{eqopt}(?:([[:space:]]*=)?)', '{eqopt}')
131
132 # we can only calculate column numbering once all substitutions done
133 i = 0
134 j = text.find(' /*COLUMN32*/ ', i)
135 while j != -1:
136   k = text.rfind('\n', 0, j)
137   col = j - k - 1
138   if col >= 32:
139     tab = ' '
140   else:
141     tab = '\t' * ((32 - col + 7) // 8)
142   text = text[:j] + tab + text[j + 14:]
143   i = j
144   j = text.find(' /*COLUMN32*/ ', i)
145
146 sys.stdout.write(text)