PageRenderTime 29ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/javacc-5.0/www/doc/JJTree.html

https://gitlab.com/essere.lab.public/qualitas.class-corpus
HTML | 620 lines | 460 code | 129 blank | 31 comment | 0 complexity | 407f529ce1ebb6c3538e8f4b55aa7b3d MD5 | raw file
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <!--
  4. Copyright (c) 2006, Sun Microsystems, Inc.
  5. All rights reserved.
  6. Redistribution and use in source and binary forms, with or without
  7. modification, are permitted provided that the following conditions are met:
  8. * Redistributions of source code must retain the above copyright notice,
  9. this list of conditions and the following disclaimer.
  10. * Redistributions in binary form must reproduce the above copyright
  11. notice, this list of conditions and the following disclaimer in the
  12. documentation and/or other materials provided with the distribution.
  13. * Neither the name of the Sun Microsystems, Inc. nor the names of its
  14. contributors may be used to endorse or promote products derived from
  15. this software without specific prior written permission.
  16. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  20. LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  21. CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  22. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  23. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  24. CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  25. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  26. THE POSSIBILITY OF SUCH DAMAGE.
  27. -->
  28. <head>
  29. <title>JavaCC: JJTree Reference</title>
  30. <!-- Changed by: Michael Van De Vanter, 14-Jan-2003 -->
  31. </head>
  32. <body bgcolor="#FFFFFF">
  33. <h1>JavaCC [tm]: JJTree Reference Documentation</h1>
  34. <h3>Introduction</h3>
  35. <p>JJTree is a preprocessor for JavaCC [tm] that inserts parse tree
  36. building actions at various places in the JavaCC source. The
  37. output of JJTree is run through JavaCC to create the parser.
  38. This document describes how to use JJTree, and how you can
  39. interface your parser to it.</p>
  40. <p>By default JJTree generates code to construct parse tree nodes
  41. for each nonterminal in the language. This behavior can be
  42. modified so that some nonterminals do not have nodes generated,
  43. or so that a node is generated for a part of a production's
  44. expansion.</p>
  45. <p>JJTree defines a Java interface Node that all parse tree nodes
  46. must implement. The interface provides methods for operations
  47. such as setting the parent of the node, and for adding children
  48. and retrieving them.</p>
  49. <p>JJTree operates in one of two modes, simple and multi (for want
  50. of better terms). In simple mode each parse tree node is of
  51. concrete type SimpleNode; in multi mode the type of the parse
  52. tree node is derived from the name of the node. If you don't
  53. provide implementations for the node classes JJTree will
  54. generate sample implementations based on SimpleNode for you.
  55. You can then modify the implementations to suit.</p>
  56. <p>Although JavaCC is a top-down parser, JJTree constructs the
  57. parse tree from the bottom up. To do this it uses a stack where
  58. it pushes nodes after they have been created. When it finds a
  59. parent for them, it pops the children from the stack and adds
  60. them to the parent, and finally pushes the new parent node
  61. itself. The stack is open, which means that you have access to
  62. it from within grammar actions: you can push, pop and otherwise
  63. manipulate its contents however you feel appropriate. See <a
  64. href="#scopes">Node Scopes and User Actions</a> below for more
  65. important information.</p>
  66. <p>JJTree provides decorations for two basic varieties of nodes,
  67. and some syntactic shorthand to make their use convenient.</p>
  68. <ol>
  69. <li>
  70. <p>A definite node is constructed with a specific number of
  71. children. That many nodes are popped from the stack and
  72. made the children of the new node, which is then pushed on
  73. the stack itself. You notate a definite node like this:</p>
  74. <p><code>#ADefiniteNode(INTEGER EXPRESSION)</code></p> <p>A
  75. definite node descriptor expression can be any integer
  76. expression, although literal integer constants are by far
  77. the most common expressions.</p>
  78. </li>
  79. <li>
  80. <p>A conditional node is constructed with all of the children
  81. that were pushed on the stack within its node scope if and
  82. only if its condition evaluates to true. If it evaluates to
  83. false, the node is not constructed, and all of the children
  84. remain on the node stack. You notate a conditional node
  85. like this:</p> <p><code>#ConditionalNode(BOOLEAN
  86. EXPRESSION)</code></p> <p>A conditional node descriptor
  87. expression can be any boolean expression. There are two
  88. common shorthands for conditional nodes:</p>
  89. <ol>
  90. <li>
  91. <p>Indefinite nodes</p> <p><code>#IndefiniteNode</code> is
  92. short for <code>#IndefiniteNode(true)</code></p>
  93. </li>
  94. <li>
  95. <p>Greater-than nodes</p> <p><code>#GTNode(>1)</code> is
  96. short for <code>#GTNode(jjtree.arity() > 1)</code></p>
  97. </li>
  98. </ol>
  99. <p>The indefinite node shorthand (1) can lead to
  100. ambiguities in the JJTree source when it is followed by a
  101. parenthesized expansion. In those cases the shorthand must
  102. be replaced by the full expression. For example:</p> <pre>
  103. ( ... ) #N ( a() ) </pre> <p>is ambiguous; you have to
  104. use the explicit condition:</p> <pre> ( ... ) #N(true) ( a()
  105. ) </pre>
  106. </li>
  107. </ol>
  108. <p>WARNING: node descriptor expressions should not have
  109. side-effects. JJTree doesn't specify how many times the
  110. expression will be evaluated.</p>
  111. <p>By default JJTree treats each nonterminal as an indefinite node
  112. and derives the name of the node from the name of its
  113. production. You can give it a different name with the following
  114. syntax:</p>
  115. <pre>
  116. void P1() #MyNode : { ... } { ... }
  117. </pre>
  118. <p>When the parser recognizes a <code>P1</code> nonterminal it
  119. begins an indefinite node. It marks the stack, so that any
  120. parse tree nodes created and pushed on the stack by nonterminals
  121. in the expansion for <code>P1</code> will be popped off and made
  122. children of the node <code>MyNode</code>.</p>
  123. <p>If you want to suppress the creation of a node for a production
  124. you can use the following syntax:</p>
  125. <pre>
  126. void P2() #void : { ... } { ... }
  127. </pre>
  128. <p>Now any parse tree nodes pushed by nonterminals in the
  129. expansion of <code>P2</code> will remain on the stack, to be
  130. popped and made children of a production further up the tree.
  131. You can make this the default behavior for non-decorated nodes
  132. by using the <code>NODE_DEFAULT_VOID</code> option.</p>
  133. <pre>
  134. void P3() : {}
  135. {
  136. P4() ( P5() )+ P6()
  137. }
  138. </pre>
  139. <p>In this example, an indefinite node <code>P3</code> is begun,
  140. marking the stack, and then a <code>P4</code> node, one or more
  141. <code>P5</code> nodes and a <code>P6</code> node are parsed.
  142. Any nodes that they push are popped and made the children of
  143. <code>P3</code>. You can further customize the generated
  144. tree:</p>
  145. <pre>
  146. void P3() : {}
  147. {
  148. P4() ( P5() )+ #ListOfP5s P6()
  149. }
  150. </pre>
  151. <p>Now the <code>P3</code> node will have a <code>P4</code> node,
  152. a <code>ListOfP5s</code> node and a <code>P6</code> node as
  153. children. The <code>#Name</code> construct acts as a postfix
  154. operator, and its scope is the immediately preceding expansion
  155. unit.</p>
  156. <h3><a name="scopes">Node Scopes and User Actions</a></h3>
  157. <p>Each node is associated with a node scope. User actions within
  158. this scope can access the node under construction by using the
  159. special identifier <code>jjtThis</code> to refer to the node.
  160. This identifier is implicitly declared to be of the correct type
  161. for the node, so any fields and methods that the node has can be
  162. easily accessed.</p>
  163. <p>A scope is the expansion unit immediately preceding the node
  164. decoration. This can be a parenthesized expression. When the
  165. production signature is decorated (perhaps implicitly with the
  166. default node), the scope is the entire right hand side of the
  167. production including its declaration block.</p>
  168. <p>You can also use an expression involving <code>jjtThis</code>
  169. on the left hand side of an expansion reference. For
  170. example:</p>
  171. <pre>
  172. ... ( jjtThis.my_foo = foo() ) #Baz ...
  173. </pre>
  174. <p>Here <code>jjtThis</code> refers to a <code>Baz</code> node,
  175. which has a field called <code>my_foo</code>. The result of
  176. parsing the production <code>foo()</code> is assigned to that
  177. <code>my_foo</code>.</p>
  178. <p>The final user action in a node scope is different from all the
  179. others. When the code within it executes, the node's children
  180. have already been popped from the stack and added to the node,
  181. which has itself been pushed onto the stack. The children can
  182. now be accessed via the node's methods such as
  183. <code>jjtGetChild()</code>.</p>
  184. <p>User actions other than the final one can only access the
  185. children on the stack. They have not yet been added to the
  186. node, so they aren't available via the node's methods.</p>
  187. <p>A conditional node that has a node descriptor expression that
  188. evaluates to false will not get added to the stack, nor have
  189. children added to it. The final user action within a
  190. conditional node scope can determine whether the node was
  191. created or not by calling the <code>nodeCreated()</code> method.
  192. This returns true if the node's condition was satisfied and the
  193. node was created and pushed on the node stack, and false
  194. otherwise.</p>
  195. <h3>Exception handling</h3>
  196. <p>An exception thrown by an expansion within a node scope that is
  197. not caught within the node scope is caught by JJTree itself.
  198. When this occurs, any nodes that have been pushed on to the node
  199. stack within the node scope are popped and thrown away. Then
  200. the exception is rethrown.</p>
  201. <p>The intention is to make it possible for parsers to implement
  202. error recovery and continue with the node stack in a known
  203. state.</p>
  204. <p>WARNING: JJTree currently cannot detect whether exceptions are
  205. thrown from user actions within a node scope. Such an exception
  206. will probably be handled incorrectly.</p>
  207. <h3><a name="hooks">Node Scope Hooks</a></h3>
  208. <p>If the <code>NODE_SCOPE_HOOK</code> option is set to true,
  209. JJTree generates calls to two user-defined parser methods on the
  210. entry and exit of every node scope. The methods must have the
  211. following signatures:</p>
  212. <pre>
  213. void jjtreeOpenNodeScope(Node n)
  214. void jjtreeCloseNodeScope(Node n)
  215. </pre>
  216. <p>If the parser is <code>STATIC</code> then these methods will
  217. have to be declared as static as well. They are both called
  218. with the current node as a parameter.</p>
  219. <p>One use might be to store the parser object itself in the
  220. node so that state that should be shared by all nodes produced
  221. by that parser can be provided. For example, the parser might
  222. maintain a symbol table.</p>
  223. <pre>
  224. void jjtreeOpenNodeScope(Node n)
  225. {
  226. ((SimpleNode)n).jjtSetValue(getSymbolTable());
  227. }
  228. void jjtreeCloseNodeScope(Node n)
  229. {
  230. }
  231. </pre>
  232. <p>Where <code>getSymbolTable()</code> is a user-defined method to
  233. return a symbol table structure for the node.</p>
  234. <h3><a name="hooks">Tracking Tokens</a></h3>
  235. <p>It is often useful to keep track of each node's first and last
  236. token so that input can be easily reproduced again. By
  237. setting the <code>TRACK_TOKENS</code> option the generated
  238. <code>SimpleNode</code> class will contain 4 extra methods:</p>
  239. <pre>
  240. public Token jjtGetFirstToken()
  241. public void jjtSetFirstToken(Token token)
  242. public Token jjtGetLastToken()
  243. public void jjtSetLastToken(Token token)
  244. </pre>
  245. <p>The first and last token for each node will be set
  246. up automatically when the parser is run. </p>
  247. <h3>The Life Cycle of a Node</h3>
  248. <p>A node goes through a well determined sequence of steps as it
  249. is built. This is that sequence viewed from the perspective of
  250. the node itself:</p>
  251. <ol>
  252. <li>the node's constructor is called with a unique integer
  253. parameter. This parameter identifies the kind of node and is
  254. especially useful in simple mode. JJTree automatically
  255. generates a file called <i>parser</i>TreeConstants.java that
  256. declares valid constants. The names of constants are derived
  257. by prepending JJT to the uppercase names of nodes, with dot
  258. symbols (&quot;.&quot;) replaced by underscore symbols
  259. (&quot;_&quot;). For convenience, an array of <code>String</code>s
  260. called <code>jjtNodeName[]</code> that maps the constants to the
  261. unmodified names of nodes is maintained in the same file.</li>
  262. <li>the node's <code>jjtOpen()</code> method is called.</li>
  263. <li>if the option <code>NODE_SCOPE_HOOK</code> is set, the
  264. user-defined parser method <code>openNodeScope()</code> is
  265. called and passed the node as its parameter. This method can
  266. initialize fields in the node or call its methods. For
  267. example, it might store the node's first token in the
  268. node.</li>
  269. <li>if an unhandled exception is thrown while the node is being
  270. parsed then the node is abandoned. JJTree will never refer to
  271. it again. It will not be closed, and the user-defined node
  272. scope hook <code>closeNodeHook()</code> will not be called
  273. with it as a parameter.</li>
  274. <li>otherwise, if the node is conditional and its conditional
  275. expression evaluates to false then the node is abandoned. It
  276. will not be closed, although the user-defined node scope hook
  277. <code>closeNodeHook()</code> might be called with it as a
  278. parameter.</li>
  279. <li>otherwise, all of the children of the node as specified by
  280. the integer expression of a definite node, or all the nodes
  281. that were pushed on the stack within a conditional node scope
  282. are added to the node. The order they are added is not
  283. specified.</li>
  284. <li>the node's <code>jjtClose()</code> method is called.</li>
  285. <li>the node is pushed on the stack.</li>
  286. <li>if the option <code>NODE_SCOPE_HOOK</code> is set, the
  287. user-defined parser method <code>closeNodeScope()</code> is
  288. called and passed the node as its parameter.</li>
  289. <li>if the node is not the root node, it is added as a child of
  290. another node and its <code>jjtSetParent()</code> method is
  291. called.</li>
  292. </ol>
  293. <h3>Visitor Support</h3>
  294. <p>JJTree provides some basic support for the visitor design
  295. pattern. If the <code>VISITOR</code> option is set to true
  296. JJTree will insert an <code>jjtAccept()</code> method into all
  297. of the node classes it generates, and also generate a visitor
  298. interface that can be implemented and passed to the nodes to
  299. accept.</p>
  300. <p>The name of the visitor interface is constructed by appending
  301. <code>Visitor</code> to the name of the parser. The interface
  302. is regenerated every time that JJTree is run, so that it
  303. accurately represents the set of nodes used by the parser. This
  304. will cause compile time errors if the implementation class has
  305. not been updated for the new nodes. This is a feature.</p>
  306. <h3>Options</h3>
  307. <p>JJTree supports the following options on the command
  308. line and in the JavaCC options statement:</p>
  309. <dl>
  310. <dt><code>BUILD_NODE_FILES</code> (default:
  311. <code>true</code>)</dt>
  312. <dd>Generate sample implementations for SimpleNode and any other
  313. nodes used in the grammar.</dd>
  314. <dt><code>MULTI</code> (default: <code>false</code>)</dt>
  315. <dd> Generate a multi mode parse tree. The default for this is
  316. false, generating a simple mode parse tree.</dd>
  317. <dt><code>NODE_DEFAULT_VOID</code> (default:
  318. <code>false</code>)</dt>
  319. <dd>Instead of making each non-decorated production an
  320. indefinite node, make it void instead.</dd>
  321. <dt><code>NODE_CLASS</code> (default: <code>""</code>)</dt>
  322. <dd>If set defines the name of a user-supplied class that will
  323. extend <code>SimpleNode</code>. Any tree nodes created will
  324. then be subclasses of NODE_CLASS.</dd>
  325. <dt><code>NODE_FACTORY</code> (default: <code>""</code>)</dt>
  326. <dd>Specify a class containing a factory method with following
  327. signature to construct nodes:
  328. <br /><code>public static Node jjtCreate(int id)</code>
  329. <br />For backwards compatibility, the value <code>false</code>
  330. may also be specified, meaning that <code>SimpleNode</code>
  331. will be used as the factory class.
  332. </dd>
  333. <dt><code>NODE_PACKAGE</code> (default: <code>""</code>)</dt>
  334. <dd> The package to generate the node classes into. The default
  335. for this is the parser package.</dd>
  336. <dt><code>NODE_EXTENDS</code> (default: <code>""</code>) <em>Deprecated</em></dt>
  337. <dd>The superclass for the SimpleNode class.
  338. By providing a custom superclass you may be able to avoid
  339. the need to edit the generated SimpleNode.java.
  340. See the examples/Interpreter for an example
  341. usage.</dd>
  342. <dt><code>NODE_PREFIX</code> (default: <code>"AST"</code>)</dt>
  343. <dd>The prefix used to construct node class names from node
  344. identifiers in multi mode. The default for this is AST.</dd>
  345. <dt><code>NODE_SCOPE_HOOK</code> (default:
  346. <code>false</code>)</dt>
  347. <dd>Insert calls to user-defined parser methods on entry and
  348. exit of every node scope. See <a href="#hooks">Node Scope
  349. Hooks above</a>.</dd>
  350. <dt><code>NODE_USES_PARSER</code> (default:
  351. <code>false</code>)</dt>
  352. <dd>JJTree will use an alternate form of the node construction
  353. routines where it passes the parser object in. For example,
  354. <pre> public static Node MyNode.jjtCreate(MyParser p, int id);
  355. MyNode(MyParser p, int id); </pre>
  356. </dd>
  357. <dt><code>TRACK_TOKENS</code> (default:
  358. <code>false</code)</dt>
  359. <dd>Insert <code>jjtGetFirstToken(), jjtSetFirstToken(), getLastToken(),
  360. </code> and <code>jjtSetLastToken()</code> methods in SimpleNode. The
  361. <code>FirstToken</code> is automatically set up on entry to a node
  362. scope; the <code>LastToken</code> is automatically set up on exit
  363. from a node scope.
  364. </dd>
  365. <dt><code>STATIC</code> (default: <code>true</code>)</dt>
  366. <dd>Generate code for a static parser. The default for this is
  367. true. This must be used consistently with the equivalent
  368. JavaCC options. The value of this option is emitted in the
  369. JavaCC source.</dd>
  370. <dt><code>VISITOR</code> (default: <code>false</code>)</dt>
  371. <dd>Insert a <code>jjtAccept()</code> method in the node
  372. classes, and generate a visitor implementation with an entry
  373. for every node type used in the grammar.</dd>
  374. <dt><code>VISITOR_DATA_TYPE</code> (default:
  375. <code>"Object"</code>)</dt>
  376. <dd>If this option is set, it is used in the signature of the
  377. generated <code>jjtAccept()</code> methods and the visit()
  378. methods as the type of the <code>data</code>
  379. argument.
  380. </dd>
  381. <dt><code>VISITOR_RETURN_TYPE</code> (default:
  382. <code>"Object"</code>)</dt>
  383. <dd>If this option is set, it is used in the signature of the
  384. generated <code>jjtAccept()</code> methods and the visit()
  385. methods as the return type of the method.
  386. </dd>
  387. <dt><code>VISITOR_EXCEPTION</code> (default:
  388. <code>""</code>)</dt>
  389. <dd>If this option is set, it is used in the signature of the
  390. generated <code>jjtAccept()</code> methods and the visit()
  391. methods.</dd>
  392. <dt><code>JJTREE_OUTPUT_DIRECTORY</code> (default:
  393. use value of <code>OUTPUT_DIRECTORY</code>)</dt>
  394. <dd>By default, JJTree generates its output in the directory
  395. specified in the global <code>OUTPUT_DIRECTORY</code> setting.
  396. Explicitly setting this option allows the user to separate the
  397. parser from the tree files.</dd>
  398. </dl>
  399. <h3>JJTree state</h3>
  400. <p>JJTree keeps its state in a parser class field called
  401. <code>jjtree</code>. You can use methods in this member to
  402. manipulate the node stack.</p>
  403. <pre>
  404. final class JJTreeState {
  405. /* Call this to reinitialize the node stack. */
  406. void reset();
  407. /* Return the root node of the AST. */
  408. Node rootNode();
  409. /* Determine whether the current node was actually closed and
  410. pushed */
  411. boolean nodeCreated();
  412. /* Return the number of nodes currently pushed on the node
  413. stack in the current node scope. */
  414. int arity();
  415. /* Push a node on to the stack. */
  416. void pushNode(Node n);
  417. /* Return the node on the top of the stack, and remove it from the
  418. stack. */
  419. Node popNode();
  420. /* Return the node currently on the top of the stack. */
  421. Node peekNode();
  422. }
  423. </pre>
  424. <h3>Node Objects</h3>
  425. <pre>
  426. /* All AST nodes must implement this interface. It provides basic
  427. machinery for constructing the parent and child relationships
  428. between nodes. */
  429. public interface Node {
  430. /** This method is called after the node has been made the current
  431. node. It indicates that child nodes can now be added to it. */
  432. public void jjtOpen();
  433. /** This method is called after all the child nodes have been
  434. added. */
  435. public void jjtClose();
  436. /** This pair of methods are used to inform the node of its
  437. parent. */
  438. public void jjtSetParent(Node n);
  439. public Node jjtGetParent();
  440. /** This method tells the node to add its argument to the node's
  441. list of children. */
  442. public void jjtAddChild(Node n, int i);
  443. /** This method returns a child node. The children are numbered
  444. from zero, left to right. */
  445. public Node jjtGetChild(int i);
  446. /** Return the number of children the node has. */
  447. int jjtGetNumChildren();
  448. }
  449. </pre>
  450. <p>The class <code>SimpleNode</code> implements the
  451. <code>Node</code> interface, and is automatically generated by
  452. JJTree if it doesn't already exist. You can use this class as a
  453. template or superclass for your node implementations, or you can
  454. modify it to suit. <code>SimpleNode</code> additionally
  455. provides a rudimentary mechanism for recursively dumping the
  456. node and its children. You might use this is in action like
  457. this:</p>
  458. <pre>
  459. {
  460. ((SimpleNode)jjtree.rootNode()).dump(">");
  461. }
  462. </pre>
  463. <p>The <code>String</code> parameter to <code>dump()</code> is
  464. used as padding to indicate the tree hierarchy.</p>
  465. <p>Another utility method is generated if the VISITOR options is set:</p>
  466. <pre>
  467. {
  468. public void childrenAccept(MyParserVisitor visitor);
  469. }
  470. </pre>
  471. <p>This walks over the node's children in turn, asking them to
  472. accept the visitor. This can be useful when implementing
  473. preorder and postorder traversals.</p>
  474. <h3>Examples</h3>
  475. <p>JJTree is distributed with some simple examples
  476. containing a grammar that parses arithmetic expressions. See
  477. the file <code>examples/JJTreeExamples/README</code> for further
  478. details.</p>
  479. <p>There is also an interpreter for a simple language that uses
  480. JJTree to build the program representation. See the file
  481. <code>examples/Interpreter/README</code> for more
  482. information.</p>
  483. <p>Information about an example using the visitor support is in
  484. <code>examples/VTransformer/README</code>.</p>
  485. </body>
  486. </html>