<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
Here is an example of .fo code that is generating missing text.
Sorry for the length of it, but it is needed to show all the code
that is missing in the PDF. In the following paragraphs, the text
beginning "Upon an assignment statement..." through "...you can pass
that infor" appears on page 1 of a chapter. The entirety of the
fo:float appears on the top of page 2, followed by no other content
on the page. Page 3 begins with the text:<br>
<br>
<blockquote>>><br>
All the expression-related rules in the parser grammar<br>
</blockquote>
<br>
Here is the FO:<br>
<br>
<fo:block id="N100DD" space-after="6pt"><br>
Upon an assignment statement, though, the recognizer must track<br>
implicit local variable definitions by using the<br>
<fo:inline font-family="Droid Sans"
font-size="90%">locals</fo:inline> <fo:inline
font-family="Droid Sans"
font-size="90%">HashMap</fo:inline>. Each<br>
variable in a list of input expressions receives a unique local<br>
variable number.<br>
</fo:block><br>
<br>
<br>
<fo:float float="before"><br>
<fo:block border-color="rgb(150, 150, 180)" border="2pt solid"
background-color="rgb(220, 220, 250)"><br>
<fo:block background-color="rgb(150, 150, 180)"
padding-bottom="3pt" padding-top="3pt" font-size="90%"
font-weight="bold" space-after="0pt" space-before="0pt"><br>
<fo:block margin-left="5pt" margin-right="5pt">Do You Ever
Need to Return a List of Templates?</fo:block><br>
</fo:block><br>
<fo:block-container margin-right="5pt" margin-left="5pt"
padding-top="3pt" font-size="85%"><br>
<fo:block/><br>
<br>
<br>
<fo:block id="N100EC" space-after="6pt"><br>
Some of you will see rules such as this:<br>
</fo:block><br>
<br>
<fo:list-block provisional-distance-between-starts="0in"
space-after.maximum="10pt" space-after.optimum="8pt"
space-after.minimum="6pt" space-before.maximum="10pt"
space-before.optimum="6pt" space-before.minimum="6pt"
font-size="80%" font-family="Droid Sans Mono"><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false" text-align="start">​prog : stat+
;</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
</fo:list-block><br>
<br>
<br>
<br>
<fo:block id="N10104" space-after="6pt"><br>
and question why <fo:inline font-family="Droid Sans"
font-size="90%">prog</fo:inline> should not return a list
of<br>
templates. Remember that for translators in the generator
category,<br>
you must literally specify what to emit for every input construct<br>
even if it is just a list of input elements. The proper generated<br>
output for <fo:inline font-family="Droid Sans"
font-size="90%">prog</fo:inline> is in fact a template that<br>
represents a list of statements. For example, you might use<br>
something akin to this:<br>
</fo:block><br>
<br>
<fo:list-block provisional-distance-between-starts="0in"
space-after.maximum="10pt" space-after.optimum="8pt"
space-after.minimum="6pt" space-before.maximum="10pt"
space-before.optimum="6pt" space-before.minimum="6pt"
font-size="80%" font-family="Droid Sans Mono"><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false" text-align="start">​prog :
(s+=stat)+ -&gt; template(stats={$s}) <fo:inline
font-style="italic" color="rgb(25, 17,
144)">"&lt;stats&gt;"</fo:inline>​</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
</fo:list-block><br>
<br>
<br>
</fo:block-container><br>
</fo:block><br>
</fo:float><br>
<br>
<fo:block id="N10125" space-after="6pt"><br>
The expression rules are as before except for the addition of code
to<br>
track the number of operations (to estimate stack size):<br>
</fo:block><br>
<br>
<br>
<br>
<fo:block id="N1012B" space-after="6pt"><br>
Once you have a parser grammar that builds the appropriate trees
and<br>
computes the number of operations and <fo:inline
font-family="Droid Sans" font-size="90%">locals</fo:inline><br>
map, you can pass that information to the tree grammar. The tree<br>
grammar will create a template for each subtree in order to emit<br>
bytecodes. Start rule <fo:inline font-family="Droid Sans"
font-size="90%">prog</fo:inline>’s template return<br>
value represents the template for the entire assembly file. The<br>
grammar itself is identical to the <fo:inline
font-family="Droid Sans" font-size="90%">Eval</fo:inline>
tree<br>
grammar from, but of course the actions<br>
are different.<br>
</fo:block><br>
<br>
<fo:block id="N10138" space-after="6pt"><br>
Here is the start of the <fo:inline font-family="Droid Sans"
font-size="90%">Gen</fo:inline> tree grammar:<br>
</fo:block><br>
<br>
<br>
<br>
<fo:block id="N10141" space-after="6pt"><br>
The test rig pulls necessary data out of the parser after parsing
is<br>
complete and passes it to the tree grammar via<br>
<fo:inline font-family="Droid Sans"
font-size="90%">prog</fo:inline> rule parameters:<br>
</fo:block><br>
<br>
<br>
<br>
<fo:block id="N1014A" space-after="6pt"><br>
<br>
</fo:block><br>
<fo:block id="N1014E" space-after="6pt"><br>
The <fo:inline font-family="Droid Sans"
font-size="90%">stat</fo:inline> rule creates an instance
of template<br>
<fo:inline font-family="Droid Sans"
font-size="90%">exprStat</fo:inline> or <fo:inline
font-family="Droid Sans"
font-size="90%">assign</fo:inline>, depending<br>
on which alternative matches:<br>
</fo:block><br>
<br>
<fo:block color="rgb(120, 155, 125)" background="rgb(200, 235,
220)" font-weight="bold" font-size="80%" font-family="Myriad"
padding-left="0.3em" space-before.maximum="10pt"
space-before.optimum="6pt" space-before.minimum="6pt"
keep-with-next="always"><br>
<fo:basic-link xmlns:exsl=<a class="moz-txt-link-rfc2396E" href="http://exslt.org/common">"http://exslt.org/common"</a>
external-destination="url(<a class="moz-txt-link-freetext" href="http://media.pragprog.com/titles/tpantlr2/code/templates/generator/2pass/Gen.g">http://media.pragprog.com/titles/tpantlr2/code/templates/generator/2pass/Gen.g</a>)">Download
templates/generator/2pass/Gen.g</fo:basic-link><br>
</fo:block><br>
<fo:list-block provisional-distance-between-starts="0in"
space-after.maximum="10pt" space-after.optimum="8pt"
space-after.minimum="6pt" space-before="0pt" font-size="80%"
font-family="Droid Sans Mono"><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false" text-align="start">​stat: expr
-&gt; exprStat(v={$expr.st},
descr={$expr.text})</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false" text-align="start">​ |
^(<fo:inline font-style="italic" color="rgb(25, 17,
144)">'='</fo:inline>​ ID expr)</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false" text-align="start">​
-&gt; assign(id={$ID.text},</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false"
text-align="start">​
descr={$text},</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false"
text-align="start">​
varNum={locals.get($ID.text)},</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false"
text-align="start">​
v={$expr.st})</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false" text-align="start">​
;</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
</fo:list-block><br>
<br>
<br>
<fo:block id="N1018D" space-after="6pt"><br>
The template specifications compute template attributes from
grammar<br>
attributes and members such as <fo:inline font-family="Droid
Sans" font-size="90%">locals</fo:inline>.<br>
</fo:block><br>
<br>
<fo:block id="N10194" space-after="6pt"><br>
Here are the templates used by rule <fo:inline
font-family="Droid Sans" font-size="90%">stat</fo:inline>:<br>
</fo:block><br>
<br>
<fo:block color="rgb(120, 155, 125)" background="rgb(200, 235,
220)" font-weight="bold" font-size="80%" font-family="Myriad"
padding-left="0.3em" space-before.maximum="10pt"
space-before.optimum="6pt" space-before.minimum="6pt"
keep-with-next="always"><br>
<fo:basic-link xmlns:exsl=<a class="moz-txt-link-rfc2396E" href="http://exslt.org/common">"http://exslt.org/common"</a>
external-destination="url(<a class="moz-txt-link-freetext" href="http://media.pragprog.com/titles/tpantlr2/code/templates/generator/2pass/ByteCode.stg">http://media.pragprog.com/titles/tpantlr2/code/templates/generator/2pass/ByteCode.stg</a>)">Download
templates/generator/2pass/ByteCode.stg</fo:basic-link><br>
</fo:block><br>
<fo:list-block provisional-distance-between-starts="0in"
space-after.maximum="10pt" space-after.optimum="8pt"
space-after.minimum="6pt" space-before="0pt" font-size="80%"
font-family="Droid Sans Mono"><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false"
text-align="start">​assign(varNum,v,descr,id) ::=
&lt;&lt;</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false" text-align="start">​; compute
&lt;descr&gt;</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false"
text-align="start">​&lt;v&gt;</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false" text-align="start">​istore
&lt;varNum&gt; ; &lt;id&gt;</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false"
text-align="start">​&gt;&gt;</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false"
text-align="start">​</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false" text-align="start">​exprStat(v,
descr) ::= &lt;&lt;</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false" text-align="start">​; compute
&lt;descr&gt;</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false"
text-align="start">​&lt;v&gt;</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
<fo:list-item relative-align="baseline"><br>
<fo:list-item-label end-indent="label-end()"
start-indent="-0.5in"><br>
<fo:block font-family="Myriad" width="0.5in" color="rgb(120, 120,
140)" font-size="65%" text-align="right"/><br>
</fo:list-item-label><br>
<fo:list-item-body end-indent="0pt" start-indent="0pt"><br>
<fo:block padding-bottom="0pt" line-height="140%"
padding-top="0pt" margin-bottom="0pt" margin-top="0pt"
wrap-option="no-wrap" white-space-treatment="preserve"
white-space-collapse="false"
text-align="start">​&gt;&gt;</fo:block><br>
</fo:list-item-body><br>
</fo:list-item><br>
</fo:list-block><br>
<br>
<br>
<fo:block id="N101D5" space-after="6pt"><br>
All the expression-related rules in the parser grammar collapse
into<br>
a single <fo:inline font-family="Droid Sans"
font-size="90%">expr</fo:inline> rule in the tree grammar:<br>
</fo:block><br>
<br>
!DSPAM:87,4d94852d63731826313041!
</body>
</html>