|
|
Initial revision
# Build token and operator tables ("toktab.c" and "optab.c")
# from token description file "tokens" and skeleton operator
# state tables in "optab".
global token, tokval, bflag, eflag, head, oper, tail, count
global restable, opertable, flagtable
global tokfile, opfile, toktab, optab
procedure tokpat()
if tab(many(' \t')) & (token := tab(upto(' \t'))) &
tab(many(' \t')) & (tokval := (tab(upto(' \t') | 0)))
then return (tab(upto('b')) & (bflag := move(1))) | (bflag := "") &
((tab(upto('e')) & (eflag := move(1))) | (eflag := "")) & pos(0)
end
procedure operpat()
return (head := tab(upto('['))) & ="[ ]" &
(tail := (tab(upto('"')) || move(1) ||
(oper := tab(upto('"'))) || move(1) || tab(0)))
end
procedure main()
local line, letter, lastletter
restable := table("")
opertable := table("")
flagtable := table("")
flagtable[""] := "0,"
flagtable["b"] := "BEGINNER,"
flagtable["e"] := "ENDER,"
flagtable["be"] := "BEGINNER+ENDER,"
count := 0
lastletter := ""
tokfile := open("tokens") | stop("tokens file missing")
opfile := open("optab") | stop("optab file missing")
toktab := open("toktab.c","w")
optab := open("optab.c","w")
# Skip the first few (non-informative) lines of "tokens"
garbage()
# Output header for "toktab.c"
write(toktab,"#include \"itran.h\"")
write(toktab,"#include \"lex.h\"")
write(toktab,"#include \"token.h\"")
write(toktab)
write(toktab,"/*")
write(toktab," * Token table - contains an entry for each token type")
write(toktab," * with printable name of token, token type, and flags")
write(toktab," * for semicolon insertion.")
write(toktab," */")
write(toktab)
write(toktab,"struct toktab toktab[] = {")
write(toktab,"/* token\t\ttoken type\tflags */")
write(toktab)
write(toktab," /* primitives */")
# Read primitive tokens and output to "toktab.c"
repeat {
write(toktab,makeline(token,tokval,bflag || eflag,count))
count +:= 1
line := read(tokfile) | stop("premature end-of-file")
line ? tokpat() | break
}
# Skip some more garbage lines
garbage()
# Output some more comments
write(toktab)
write(toktab," /* reserved words */")
# Read in reserved words, output them,
# and build table of first letters.
repeat {
write(toktab,makeline(token,tokval,bflag || eflag,count))
letter := token[1]
if letter ~== lastletter then {
lastletter := letter
restable[letter] := count
}
count +:= 1
line := read(tokfile) | stop("premature end-of-file")
if line ? tokpat() then next else break
}
# Skip more garbage
garbage()
# Another comment
write(toktab)
write(toktab," /* operators */")
# Read in operators, output them, and build table
repeat {
write(toktab,makeline(token,tokval,bflag || eflag,count))
opertable[token] := count
count +:= 1
line := read(tokfile) | stop("premature end-of-file")
line ? tokpat() | break
}
eof()
end
procedure eof() # output end of token table and reserveed word first-letter index.
local line
write(toktab,makeline("end-of-file","0","",""))
write(toktab," };")
write(toktab)
write(toktab,"/*")
write(toktab," * restab[c] points to the first keyword in toktab which")
write(toktab," * begins with the letter c.")
write(toktab," */")
write(toktab)
write(toktab,"struct toktab *restab[] = {")
write(toktab," NULL , NULL , /* _` */")
write(toktab,makeres("abcd"))
write(toktab,makeres("efgh"))
write(toktab,makeres("ijkl"))
write(toktab,makeres("mnop"))
write(toktab,makeres("qrst"))
write(toktab,makeres("uvwx"))
write(toktab,makeres("yz"))
write(toktab," };")
close(toktab)
# Read through operator state table skeleton, inserting
# token numbers for operators.
repeat {
while line := read(opfile) | break break do {
if line ? operpat() then break
else write(optab,line)
}
if /opertable[oper] then write("no entry for",oper)
else write(optab,head,"[",right(opertable[oper],3),"]",tail)
}
end
procedure makeline(token,tokval,flag,count) # build an output line for token table.
local line
line := left(" \"" || token || "\",",22) || left(tokval || ",",15)
flag := flagtable[flag]
if count ~=== "" then flag := left(flag,19)
line ||:= flag
if count ~=== "" then line ||:= "/* " || right(count,3) || " */"
return line
end
procedure makeres(lets) # build an output line for reserved word index.
local let, letters, line
line := " "
letters := lets
every let := !lets do
if restable[let] ~=== "" then line ||:= "&toktab[" ||
right(restable[let],2) || "], "
else line ||:= "NULL, "
return left(line,55) || "/* " || letters || " */"
end
procedure garbage()
local line
while line := read(tokfile) | stop("premature end-of-file") do
if line ? tokpat() then return
end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.