forked from intel/device-modeling-language
-
Notifications
You must be signed in to change notification settings - Fork 0
/
grammar_to_md.py
127 lines (117 loc) · 4.72 KB
/
grammar_to_md.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# © 2021-2023 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
# Convert a parser.out file fron yacc.py to jDOCU format
import sys
import re
from pathlib import Path
(dmlpath, infile, outfile) = sys.argv[1:]
sys.path.append(dmlpath)
from dml.dmllex14 import reserved_idents, keywords_dml14
from dml.dmllex12 import keywords_dml12
r = re.compile(r'^Rule ..... ([A-Za-z_][\w_]*) -> (.*)$')
terminals = { 'PLUS' : '"<b>+</b>"',
'MINUS' : '"<b>-</b>"',
'TIMES' : '"<b>*</b>"',
'DIVIDE' : '"<b>/</b>"',
'MOD' : '"<b>%</b>"',
'BOR' : '"<b>|</b>"',
'BAND' : '"<b>&</b>"',
'BNOT' : '"<b>~</b>"',
'BXOR' : '"<b>^</b>"',
'LSHIFT' : '"<b><<</b>"',
'RSHIFT' : '"<b>>></b>"',
'LOR' : '"<b>||</b>"',
'LAND' : '"<b>&&</b>"',
'LNOT' : '"<b>!</b>"',
'LT' : '"<b><</b>"',
'LE' : '"<b><=</b>"',
'GT' : '"<b>></b>"',
'GE' : '"<b>>=</b>"',
'EQ' : '"<b>==</b>"',
'NE' : '"<b>!=</b>"',
'EQUALS' : '"<b>=</b>"',
'TIMESEQUAL' : '"<b>*=</b>"',
'DIVEQUAL' : '"<b>/=</b>"',
'MODEQUAL' : '"<b>%=</b>"',
'PLUSEQUAL' : '"<b>+=</b>"',
'MINUSEQUAL' : '"<b>-=</b>"',
'LSHIFTEQUAL' : '"<b><<=</b>"',
'RSHIFTEQUAL' : '"<b>>>=</b>"',
'BANDEQUAL' : '"<b>&=</b>"',
'BXOREQUAL' : '"<b>^=</b>"',
'BOREQUAL' : '"<b>|=</b>"',
'PLUSPLUS' : '"<b>++</b>"',
'MINUSMINUS' : '"<b>--</b>"',
'ARROW' : '"<b>-></b>"',
'CONDOP' : '"<b>?</b>"',
'HASHCONDOP' : '<b>#?</b>',
'LPAREN' : '"<b>(</b>"',
'RPAREN' : '"<b>)</b>"',
'LBRACKET' : '"<b>[</b>"',
'RBRACKET' : '"<b>]</b>"',
'LBRACE' : '"<b>{</b>"',
'RBRACE' : '"<b>}</b>"',
'COMMA' : '"<b>,</b>"',
'PERIOD' : '"<b>.</b>"',
'SEMI' : '"<b>;</b>"',
'COLON' : '"<b>:</b>"',
'HASHCOLON' : '<b>#:</b>',
'AT' : '"<b>@</b>"',
'DOLLAR' : '"<b>$</b>"',
'DOTDOT' : '"<b>..</b>"',
'HASH' : '"<b>#</b>"',
'CBLOCK' : '"<b>%{ ... %}</b>"',
'HASHIF' : '"<b>#if</b>"',
'HASHELSE' : '"<b>#else</b>"',
'HASHSELECT' : '"<b>#select</b>"',
'HASHFOREACH' : '"<b>#foreach</b>"',
'ID' : '<i>identifier</i>',
'CCONST' : '<i>char-literal</i>',
'SCONST' : '<i>string-literal</i>',
'ICONST' : '<i>integer-literal</i>',
'HCONST' : '<i>hex-literal</i>',
'BCONST' : '<i>binary-literal</i>',
'FCONST' : '<i>float-literal</i>',
'ELLIPSIS' : '<i>"..."</i>',
'<empty>' : '<empty>'
}
for k in (reserved_idents
+ tuple(keywords_dml14.values())
+ tuple(keywords_dml12.values())):
terminals[k] = '<b>%s</b>' % k.lower()
nonterminals = []
rules = []
current_term = None
current_prods = []
for line in Path(infile).read_text().splitlines():
m = r.match(line)
if not m:
continue
term = m.group(1)
prod = m.group(2).split()
if term == current_term:
current_prods.append(prod)
else:
nonterminals.append(term)
current_term = term
current_prods = [prod]
rules.append((current_term, current_prods))
with open(outfile, 'w') as f:
f.write('# Formal Grammar\n')
f.write('<dl>\n')
for term, prods in rules:
f.write(f'<dt><i>{term}</i> →</dt>\n')
s = ''
f.write('<dd>\n')
for prod in prods:
if 'error' in prod:
continue
f.write(s + ' ')
for x in prod:
if x in nonterminals:
f.write(f'<i> {x} </i> ')
else:
f.write(f'{terminals[x]} ')
s = '<br/><b>|</b>'
f.write('</dd>\n')
f.write('</dl>\n')