diff options
Diffstat (limited to 'ipl/packs/ibpag2/ibwriter.icn')
-rw-r--r-- | ipl/packs/ibpag2/ibwriter.icn | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/ipl/packs/ibpag2/ibwriter.icn b/ipl/packs/ibpag2/ibwriter.icn new file mode 100644 index 0000000..8bf0263 --- /dev/null +++ b/ipl/packs/ibpag2/ibwriter.icn @@ -0,0 +1,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 |