GLR Actions - RopleyIT/GLRParser GitHub Wiki

The NonTerminalToken class

When a merge function is called, it is passed two parameters that contain the two parse trees for the set of tokens that reduced to the non-terminal token at the left hand side of the rule being merged. Each parameter is an instance of the class NonTerminalToken, which is described here.

The NonTerminalToken class implements the IToken interface, just the same as the input sequence of events or tokens that feed the parser. Hence objects of this class have all the properties and methods expected for that interface. In addition, objects of this class also have an indexable property called Children that contains the ordered list of child tokens that were reduced to the current non-terminal token in a previous reduction. The details for each of these properties is given below.

PROPERTY DESCRIPTION
int Type Returns the integer value of the non-terminal token type from the parser. This can be used as an index into the parser's Tokens property to find the character string name of the non-terminal token in the grammar. This property is required by the IToken interface that the NonTerminalToken class implements.
string Position  This is part of the IToken interface. If filled in by the input tokeniser for the parser, this gives position information for a given token, and is typically used to help a developer spot where an error occurred in a parser's input sequence. For a NonTerminalToken, this returns the Position value for the leftmost input token in the reduction.
IToken[] Children This is the list of tokens (terminal and non-terminal) from the right hand side of the grammar rule that was reduced to the current NonTerminalToken. Note that some of these might be of type ParserToken (or some other implementation of IToken returned by the input tokeniser) if they are terminal tokens, and some will be of type NonTerminalToken because ther parser has progressed through several reductions to reach the current NonTerminalToken. Hence the current object is the root of a parse tree that describes how all its constituent input tokens were parsed, and reduced into a particular configuration of non-terminals and terminals.
object Value Returns the computed value of the current NonTerminalToken. This is part of the IToken interface. The first time this is read, it executes the various action functions of the rule reductions that led to this particular NonTerminalToken. These action functions each return the values to be assigned to their various NonTerminalToken objects in the same order they would have been executed in an LR(1) parse. Hence you should not try to read the Value property until you are ready for any side effects of these action functions to take place. Note that the value is cached in the object after the first time it is read. Equally important to note, it is possible that none of the action functions have been executed even though the parse of the input tokens is over. This is because the execution of the action functions has been deferred until you have merged, thus selecting just one of the candidate parses. To force the action functions to be executed, you must read the Value property of the NonTerminalToken returned by the grammar's top level non-terminal token.

When you write the merge code for the reductions to a particular non terminal, you will need to use the structure of the parse tree as determined by the hierarchy found in the Children property, and (if safe to call them) the values returned by the various Value properties for each token in the tree. This is the information available to you to help decide which reduction to keep, and which to discard. If you keep both, and let the decision be made later in the parse, you may have more information to help you make the correct decision. However, the parse trees passed to the merge function will be deeper and more complicated to navigate.

Examine the merge code found in the description of how to write inline merge functions. See how the top two levels of the tree beneath the expression node are inspected to see which way round the tree should be based on operator precedence. Notice the use of the Children property, and the checks that the various child nodes are NonTerminalTokens. Notice also how the GLR parser will have produced both the wrong and the correct reductions of the input token sequence, and passed them both to the merge function. All the merge function is doing is discarding the one that has interpreted the operator precedence wrongly.

⚠️ **GitHub.com Fallback** ⚠️