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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
implement Sh9Parser;
include "sys.m";
include "sh9parser.m";
include "sh9util.m";
sys: Sys;
S_UNKNOWN: con "UNK";
sh9u: Sh9Util;
reverse_list: import sh9u;
to_array: import sh9u;
GrammarNode.print_expr(gn: self ref GrammarNode) {
lg:= len gn.expr;
for (i:=0; i<lg; i++) {
sys->print("%s ", gn.expr[i]);
}
if (gn.transform == S_UNKNOWN) {
sys->print("\n");
} else {
sys->print("-> %s\n", gn.transform);
}
}
init()
{
sys = load Sys Sys->PATH;
sh9u = load Sh9Util Sh9Util->PATH;
}
mk_tok(start: int, line: int, tok: string, typ: string) : ref TokNode {
tok_node: TokNode;
tok_node.start = start;
tok_node.line = line;
tok_node.tok = tok;
tok_node.typ = typ;
return ref tok_node;
}
set_last_tok(last_tok: ref TokNode, toks: list of ref TokNode): (ref TokNode, list of ref TokNode) {
sys->print("last_tok: %s\n", last_tok.typ);
ret_tok: TokNode;
#ret_tok = *last_tok;
ret_tok.typ = last_tok.typ;
ret_tok.start = last_tok.start;
ret_tok.tok = last_tok.tok;
ret_tok.line = last_tok.line;
if (last_tok.typ != S_UNKNOWN) {
toks = last_tok :: toks;
ret_tok.typ = S_UNKNOWN;
ret_tok.start = -1;
ret_tok.tok = "";
ret_tok.line = -1;
}
sys->print("ret_tok: %s\n", ret_tok.typ);
return (ref ret_tok, toks);
}
print_toks(toks: array of ref TokNode) {
lt := len toks;
for (i := 0; i < lt; i ++) {
tok := toks[i];
sys->print("[%d/%d] %s (%s)\n", i, lt, tok.typ, tok.tok);
}
}
print_toks_short(toks: array of ref TokNode) {
lt := len toks;
for (i := 0; i < lt; i ++) {
tok := toks[i];
sys->print("%s ", tok.typ);
}
sys->print("\n");
}
check_grammar_node_match(toks: array of ref TokNode, gn: ref GrammarNode): int {
lt:= len toks;
lg:= len gn.expr;
if (lg > lt) {
return 0;
}
#sys->print("Checking grammar ");
gn.print_expr();
#sys->print("Against ");
print_toks(toks);
for (i:= 0; i < lg; i ++) {
if (toks[i].typ != gn.expr[i]) {
return 0;
}
}
return 1;
}
replace_toks(src: array of ref TokNode, replace_start: int, replace_len: int, replace_with: array of ref TokNode): array of ref TokNode {
src_len:= len src;
new_toks: list of ref TokNode;
with_len:= len replace_with;
for (i:=0; i<replace_start; i++) {
new_toks = src[i] :: new_toks;
}
for (i=0; i<with_len; i++) {
new_toks = replace_with[i] :: new_toks;
}
for (i=replace_start + replace_len; i<src_len; i++) {
new_toks = src[i] :: new_toks;
}
new_toks = reverse_list(new_toks);
return to_array(new_toks);
}
parse_toks(toks: array of ref TokNode, g: array of ref GrammarNode): array of ref TokNode {
lgns := len g;
changed := 0;
ctr := 0;
do
{
lt := len toks;
sys->print("Loop %d: ", ctr);
print_toks_short(toks);
ctr ++;
changed = 0;
fast: for (i := 0; i <= lt; i ++) {
for (j := 0; j < lgns; j++) {
gj:= g[j];
if (check_grammar_node_match(toks[lt - i:], gj) == 1) {
sys->print("Something matched !\n");
gj.print_expr();
sys->print("Before replace: ");
print_toks_short(toks);
gj.callback(toks[lt-i: lt-i+len gj.expr]);
toks = replace_toks(toks, lt-i, len gj.expr, array[] of {mk_tok(toks[lt - i].start, toks[lt - i].line, "", gj.transform)});
sys->print("After replace: ");
changed = 1;
break fast;
}
}
}
} while(changed);
return toks;
}
|