|
|
1.1 root 1: # Build token and operator tables ("toktab.c" and "optab.c")
2: # from token description file "tokens" and skeleton operator
3: # state tables in "optab".
4:
5: global token, tokval, bflag, eflag, head, oper, tail, count
6: global restable, opertable, flagtable
7: global tokfile, opfile, toktab, optab
8:
9: procedure tokpat()
10: if tab(many(' \t')) & (token := tab(upto(' \t'))) &
11: tab(many(' \t')) & (tokval := (tab(upto(' \t') | 0)))
12: then return (tab(upto('b')) & (bflag := move(1))) | (bflag := "") &
13: ((tab(upto('e')) & (eflag := move(1))) | (eflag := "")) & pos(0)
14: end
15:
16: procedure operpat()
17: return (head := tab(upto('['))) & ="[ ]" &
18: (tail := (tab(upto('"')) || move(1) ||
19: (oper := tab(upto('"'))) || move(1) || tab(0)))
20: end
21:
22: procedure main()
23: local line, letter, lastletter
24: restable := table("")
25: opertable := table("")
26: flagtable := table("")
27: flagtable[""] := "0,"
28: flagtable["b"] := "BEGINNER,"
29: flagtable["e"] := "ENDER,"
30: flagtable["be"] := "BEGINNER+ENDER,"
31: count := 0
32: lastletter := ""
33:
34: tokfile := open("tokens") | stop("tokens file missing")
35: opfile := open("optab") | stop("optab file missing")
36: toktab := open("toktab.c","w")
37: optab := open("optab.c","w")
38:
39: # Skip the first few (non-informative) lines of "tokens"
40:
41: garbage()
42:
43: # Output header for "toktab.c"
44: write(toktab,"#include \"itran.h\"")
45: write(toktab,"#include \"lex.h\"")
46: write(toktab,"#include \"token.h\"")
47: write(toktab)
48: write(toktab,"/*")
49: write(toktab," * Token table - contains an entry for each token type")
50: write(toktab," * with printable name of token, token type, and flags")
51: write(toktab," * for semicolon insertion.")
52: write(toktab," */")
53: write(toktab)
54: write(toktab,"struct toktab toktab[] = {")
55: write(toktab,"/* token\t\ttoken type\tflags */")
56: write(toktab)
57: write(toktab," /* primitives */")
58:
59: # Read primitive tokens and output to "toktab.c"
60:
61: repeat {
62: write(toktab,makeline(token,tokval,bflag || eflag,count))
63: count +:= 1
64: line := read(tokfile) | stop("premature end-of-file")
65: line ? tokpat() | break
66: }
67:
68: # Skip some more garbage lines
69:
70: garbage()
71:
72: # Output some more comments
73:
74: write(toktab)
75: write(toktab," /* reserved words */")
76:
77: # Read in reserved words, output them,
78: # and build table of first letters.
79:
80: repeat {
81: write(toktab,makeline(token,tokval,bflag || eflag,count))
82: letter := token[1]
83: if letter ~== lastletter then {
84: lastletter := letter
85: restable[letter] := count
86: }
87: count +:= 1
88: line := read(tokfile) | stop("premature end-of-file")
89: if line ? tokpat() then next else break
90: }
91:
92: # Skip more garbage
93:
94: garbage()
95:
96: # Another comment
97:
98: write(toktab)
99: write(toktab," /* operators */")
100:
101: # Read in operators, output them, and build table
102:
103: repeat {
104: write(toktab,makeline(token,tokval,bflag || eflag,count))
105: opertable[token] := count
106: count +:= 1
107: line := read(tokfile) | stop("premature end-of-file")
108: line ? tokpat() | break
109: }
110: eof()
111: end
112:
113: procedure eof() # output end of token table and reserveed word first-letter index.
114: local line
115: write(toktab,makeline("end-of-file","0","",""))
116: write(toktab," };")
117: write(toktab)
118: write(toktab,"/*")
119: write(toktab," * restab[c] points to the first keyword in toktab which")
120: write(toktab," * begins with the letter c.")
121: write(toktab," */")
122: write(toktab)
123: write(toktab,"struct toktab *restab[] = {")
124: write(toktab," NULL , NULL , /* _` */")
125: write(toktab,makeres("abcd"))
126: write(toktab,makeres("efgh"))
127: write(toktab,makeres("ijkl"))
128: write(toktab,makeres("mnop"))
129: write(toktab,makeres("qrst"))
130: write(toktab,makeres("uvwx"))
131: write(toktab,makeres("yz"))
132: write(toktab," };")
133: close(toktab)
134:
135: # Read through operator state table skeleton, inserting
136: # token numbers for operators.
137:
138: repeat {
139: while line := read(opfile) | break break do {
140: if line ? operpat() then break
141: else write(optab,line)
142: }
143: if /opertable[oper] then write("no entry for",oper)
144: else write(optab,head,"[",right(opertable[oper],3),"]",tail)
145: }
146: end
147:
148: procedure makeline(token,tokval,flag,count) # build an output line for token table.
149: local line
150: line := left(" \"" || token || "\",",22) || left(tokval || ",",15)
151: flag := flagtable[flag]
152: if count ~=== "" then flag := left(flag,19)
153: line ||:= flag
154: if count ~=== "" then line ||:= "/* " || right(count,3) || " */"
155: return line
156: end
157:
158: procedure makeres(lets) # build an output line for reserved word index.
159: local let, letters, line
160: line := " "
161: letters := lets
162: every let := !lets do
163: if restable[let] ~=== "" then line ||:= "&toktab[" ||
164: right(restable[let],2) || "], "
165: else line ||:= "NULL, "
166: return left(line,55) || "/* " || letters || " */"
167: end
168:
169: procedure garbage()
170: local line
171: while line := read(tokfile) | stop("premature end-of-file") do
172: if line ? tokpat() then return
173: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.