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
|
############################################################################
#
# Name: ibwriter.icn
#
# Title: Ibpag2 parser/library writer
#
# Author: Richard L. Goerwitz
#
# Version: 1.7
#
############################################################################
#
# Given a grammar, an action table, a goto table, an open output
# file, an open iiparser file, and a module name, sends to the output
# file a fully loaded LR parser with run-time constructible action
# and goto tables. The iiparser file contains the base LR parser
# that the output file uses.
#
############################################################################
#
# Links: itokens, ximage
#
# See also: iiparse.icn
#
############################################################################
#link itokens, ximage
link ximage
# defined in itokens.icn
# record ib_TOK(sym, str)
procedure ibwriter(iiparse_file, outfile, grammar, atbl, gtbl, module)
local token, next_token, start_symbol, rule_list, ttbl
/module := ""
start_symbol := grammar.start
rule_list := grammar.rules
ttbl := grammar.tbl
next_token := create itokens(iiparse_file, 1)
#
# Copy tokens in iiparse_file to outfile. Whenever we find a $
# (RHSARG), process: If we find $$, output $; If we find $module,
# output image(module); and other such stuff. Note that
# copy_iiparse_tokens suspends tokens before writing them. It
# also blocks writing of any token whose sym field matches the
# string given as arg 3.
#
every token := copy_iiparse_tokens(next_token, outfile, "RHSARG")
do {
if token.sym == "RHSARG" then {
if (token := @next_token).sym == "RHSARG" then {
writes(outfile, token.str)
next
}
token.sym == "IDENT" | iohno(60, "line "|| line_number)
writes(outfile, " ")
case token.str of {
# copy $module name over as a literal
"module" : writes(outfile, image(module))
# use ximage to copy over action, goto, and token tables,
# as well as the production list (used only for debugging)
"atbl_insertion_point": writes(outfile, ximage(atbl))
"gtbl_insertion_point": writes(outfile, ximage(gtbl))
"ttbl_insertion_point": writes(outfile, ximage(ttbl))
"rule_list_insertion_point" :
writes(outfile, ximage(rule_list))
# use image to copy the start symbol into the output file
"start_symbol_insertion_point" :
writes(outfile, image(start_symbol))
# add the module name to anything else beginning with $
default : writes(outfile, token.str, module, " ")
}
}
}
return
end
#
# copy_iiparse_tokens: coexpression x file x string -> ib_TOK records
# (next_token, out, except) -> token records
#
# Copy Icon code to output stream, also suspending as we go.
# Insert separators between tokens where needed. Do not output
# any token whose sym field matches except. The point in
# suspending tokens as we go is to enable the calling procedure to
# look for signal tokens that indicate insertion or termination
# points. Fail on EOF.
#
procedure copy_iiparse_tokens(next_token, out, except)
local separator, T
separator := ""
while T := @next_token do {
if \T.sym then suspend T
if \T.sym == \except then next
if any(&digits ++ &letters ++ '_.', \T.str, 1, 2) & \T.sym ~== "DOT"
then writes(out, separator)
writes(out, T.str)
if any(&digits ++ &letters ++ '_.', \T.str, -1, 0) & \T.sym ~== "DOT"
then separator := " " else separator := ""
}
end
|