Enhanced C#
Language of your choice: library documentation
|
A class that implements this interface will generate small bits of code that the parser generator will use. The default implementation is IntStreamCodeGenHelper. To install a new code generator, set the LLParserGenerator.CodeGenHelper property or supply the generator in the constructor of LLParserGenerator. More...
A class that implements this interface will generate small bits of code that the parser generator will use. The default implementation is IntStreamCodeGenHelper. To install a new code generator, set the LLParserGenerator.CodeGenHelper property or supply the generator in the constructor of LLParserGenerator.
Two of these methods (VisitInput and FromCode) are called by the LLLPG macro. All the others are called by the main engine and its helper classes in LLParserGenerator.
Note that some parts of the code (the outer skeleton–if, while, for statements) are still generated by LLParserGenerator.GenerateCodeVisitor.
Properties | |
IPGTerminalSet | EmptySet [get] |
Returns an empty set of the appropriate type for the kind of parser being generated by this code. More... | |
Public Member Functions | |
LNode | VisitInput (LNode stmt, IMessageSink sink) |
In case the IPGCodeGenHelper is interested, the LLLPG macro calls this method on each statement in the body of the macro (as a preprocessing step, before LLLPG looks at it). No action is required. More... | |
Pred | CodeToTerminalPred (LNode expr, ref string errorMsg) |
Creates a terminal predicate from a code expression. More... | |
IPGTerminalSet | Optimize (IPGTerminalSet set, IPGTerminalSet dontcare) |
Simplifies the specified set, if possible, so that GenerateTest() can generate simpler code for an if-else chain in a prediction tree. More... | |
char | ExampleChar (IPGTerminalSet set) |
Returns an example of a character in the set, or null if this is not a set of characters or if EOF is the only member of the set. More... | |
string | Example (IPGTerminalSet set) |
Returns an example of an item in the set. If the example is a character, it should be surrounded by single quotes. More... | |
void | Begin (WList< LNode > classBody, ISourceFile sourceFile) |
Before the parser generator generates code, it calls this method. More... | |
void | BeginRule (Rule rule) |
Notifies the snippet generator that code generation is starting for a new rule. More... | |
void | Done () |
LLParserGenerator calls this method to notify the snippet generator that code generation is complete. More... | |
LNode | TerminalType [get] |
Type of variables auto-declared when you use labels in your grammar (e.g. x:Foo (list+:Bar)*) More... | |
LNode | GenerateSkip (bool savingResult) |
Generate code to match any token. More... | |
LNode | GenerateAndPredCheck (AndPred andPred, LNode code, int lookaheadAmt) |
Generate code to check an and-predicate during or after prediction, e.g. &!{foo} becomes !(foo) during prediction and Check(!(foo)); afterward. More... | |
LNode | GenerateMatch (IPGTerminalSet set_, bool savingResult, bool recognizerMode) |
Generate code to match a set, e.g. MatchRange('a', 'z'); or MatchExcept(' . If the set is too complex, a declaration for it is created in the classBody which was passed to Begin() . More... | |
LNode | LA (int k) |
Generates code to read LA(k). More... | |
LNode | LAType () |
Returns the data type of LA(k) More... | |
LNode | ErrorBranch (IPGTerminalSet covered, int laIndex) |
Generates code for the error branch of prediction. More... | |
bool | ShouldGenerateSwitch (IPGTerminalSet[] branchSets, MSet< int > casesToInclude, bool hasErrorBranch) |
Returns true if a "switch" statement is the preferable code generation technique rather than the default if-else chain More... | |
LNode | GenerateSwitch (IPGTerminalSet[] branchSets, MSet< int > casesToInclude, LNode[] branchCode, LNode defaultBranch, LNode laVar) |
Generates a switch statement with the specified branches where branchCode[i] is the code to run if the input is in the set branchSets[i]. More... | |
LNode | GenerateTest (IPGTerminalSet set, LNode laVar) |
Generates code to test whether the terminal denoted 'laVar' is in the set. More... | |
LNode | CreateRuleMethod (Rule rule, VList< LNode > methodBody) |
Generates the method for a rule, given the method's contents. More... | |
LNode | CreateTryWrapperForRecognizer (Rule rule) |
Generates the try-wrapper for a recognizer rule. More... | |
LNode | CallRule (RuleRef rref, bool recognizerMode) |
Generates code to call a rule based on rref.Rule.Name and rref.Params . More... | |
LNode | CallTryRecognizer (RuleRef rref, int lookahead) |
Generates a call to the Try_Scan_*() function that wraps around a Scan_*() recognizer. Called while generating code for an and-pred. More... | |
LNode | GetListType (LNode type) |
Gets the list type for elements of the specified type (e.g. List<type>) More... | |
LNode | MakeInitializedVarDecl (LNode type, bool wantList, Symbol varName) |
Gets a variable declaration for the specified type, e.g. if type is Foo and wantList == true and varName.Name == "x" , the statement returned might be List<Foo> x = new List<Foo>(); More... | |
LNode | ResolveAlias (LNode node) |
Returns the node for an alias. If the specified node is not an alias, returns the same node unchanged. More... | |
void Loyc.LLParserGenerator.IPGCodeGenHelper.Begin | ( | WList< LNode > | classBody, |
ISourceFile | sourceFile | ||
) |
Before the parser generator generates code, it calls this method.
classBody | the body (braced block) of the class where the code will be generated, which allows the snippet generator to add code at class level when needed. |
sourceFile | the suggested ISourceFile to assign to generated code snippets. |
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
Notifies the snippet generator that code generation is starting for a new rule.
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
Generates code to call a rule based on rref.Rule.Name
and rref.Params
.
For a normal rule call, this method should return rref.AutoSaveResult(code)
where code
is the code to invoke the rule.
Recognizer mode is normally implemented by calling the recognizer version of the rule in an "if" statement: if (!Scan_Foo()) return false;
Backtrack mode expects a boolean expression to be returned, normally something like Try_Scan_Foo()
where the name Try_Is_Foo
comes from the recognizer's Rule.TryWrapperName.
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
Generates a call to the Try_Scan_*() function that wraps around a Scan_*() recognizer. Called while generating code for an and-pred.
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
Creates a terminal predicate from a code expression.
expr | A expression provided by the user, such as "a string" , a Token.Type , or a value..range . expr will not be a call to the inversion operator #~ (that's handled internally using IPGTerminalSet.Inverted()). This method also handles the "any token" input, which is an underscore by convention (_). |
errorMsg | An error message to display. If the method returns null, the LLLPG macro shows this as an error; if this method does not return null, the message (if provided) is shown as a warning. |
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase, Loyc.LLParserGenerator.GeneralCodeGenHelper, and Loyc.LLParserGenerator.IntStreamCodeGenHelper.
LNode Loyc.LLParserGenerator.IPGCodeGenHelper.CreateRuleMethod | ( | Rule | rule, |
VList< LNode > | methodBody | ||
) |
Generates the method for a rule, given the method's contents.
rule | Rule for which a method is needed. |
methodBody | A list of statements produced by LLParserGenerator inside the method. |
To generate the default method, simply call Rule.CreateMethod(VList{LNode}).
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
Generates the try-wrapper for a recognizer rule.
To generate the default method, simply call rule.CreateTryWrapperForRecognizer()
.
Recognizers consist of two methods: the recognizer itself and the try-wrapper, if it is needed by the grammar. For example, the recognizer version of this rule:
is this pair of methods:
The Try*
helper method is called from normal rules that use an zero-width assertion (&Hello
), while the recognizer method Scan_*
is called from other recognizers that call the rule normally (i.e. NOT using an and-predicate). By the way, the LLLPG core removes actions like _foo++
from the recognizer version.
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
void Loyc.LLParserGenerator.IPGCodeGenHelper.Done | ( | ) |
LLParserGenerator calls this method to notify the snippet generator that code generation is complete.
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
LNode Loyc.LLParserGenerator.IPGCodeGenHelper.ErrorBranch | ( | IPGTerminalSet | covered, |
int | laIndex | ||
) |
Generates code for the error branch of prediction.
covered | The permitted token set, which the input did not match. NOTE: if the input matched but there were and-predicates that did not match, this parameter will be null (e.g. the input is 'b' in (&{x} 'a' | &{y} 'b') , but y is false). |
laIndex | Lookahead amount at which the error branch is being created. |
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
string Loyc.LLParserGenerator.IPGCodeGenHelper.Example | ( | IPGTerminalSet | set | ) |
Returns an example of an item in the set. If the example is a character, it should be surrounded by single quotes.
This helps produce error messages in LLLPG.
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase, Loyc.LLParserGenerator.IntStreamCodeGenHelper, and Loyc.LLParserGenerator.GeneralCodeGenHelper.
char Loyc.LLParserGenerator.IPGCodeGenHelper.ExampleChar | ( | IPGTerminalSet | set | ) |
Returns an example of a character in the set, or null if this is not a set of characters or if EOF is the only member of the set.
This helps produce error messages in LLLPG.
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase, and Loyc.LLParserGenerator.IntStreamCodeGenHelper.
LNode Loyc.LLParserGenerator.IPGCodeGenHelper.GenerateAndPredCheck | ( | AndPred | andPred, |
LNode | code, | ||
int | lookaheadAmt | ||
) |
Generate code to check an and-predicate during or after prediction, e.g. &!{foo}
becomes !(foo)
during prediction and Check(!(foo));
afterward.
andPred | Predicate for which an expression has already been generated |
code | The expression to be checked |
lookaheadAmt | Current lookahead amount. -1 means "prediction is complete, generate a Check() statement". |
LLLPG substitutes $LI and $LA before it calls this method.
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
LNode Loyc.LLParserGenerator.IPGCodeGenHelper.GenerateMatch | ( | IPGTerminalSet | set_, |
bool | savingResult, | ||
bool | recognizerMode | ||
) |
Generate code to match a set, e.g. MatchRange('a', 'z');
or MatchExcept('
. If the set is too complex, a declaration for it is created in the
', ''); }classBody
which was passed to Begin()
.
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
LNode Loyc.LLParserGenerator.IPGCodeGenHelper.GenerateSkip | ( | bool | savingResult | ) |
Generate code to match any token.
Skip(); }
, or MatchAny(); } if the result is to be saved.Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
LNode Loyc.LLParserGenerator.IPGCodeGenHelper.GenerateSwitch | ( | IPGTerminalSet[] | branchSets, |
MSet< int > | casesToInclude, | ||
LNode[] | branchCode, | ||
LNode | defaultBranch, | ||
LNode | laVar | ||
) |
Generates a switch statement with the specified branches where branchCode[i] is the code to run if the input is in the set branchSets[i].
casesToInclude | The set chosen by ShouldGenerateSwitch. |
defaultBranch | Code to be placed in the default: case (if none, the blank stmt @``; ) |
laVar | The lookahead variable being switched on (e.g. la0) |
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
LNode Loyc.LLParserGenerator.IPGCodeGenHelper.GenerateTest | ( | IPGTerminalSet | set, |
LNode | laVar | ||
) |
Generates code to test whether the terminal denoted 'laVar' is in the set.
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
Gets the list type for elements of the specified type (e.g. List<type>)
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
LNode Loyc.LLParserGenerator.IPGCodeGenHelper.LA | ( | int | k | ) |
Generates code to read LA(k).
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase, and Loyc.LLParserGenerator.GeneralCodeGenHelper.
LNode Loyc.LLParserGenerator.IPGCodeGenHelper.LAType | ( | ) |
Returns the data type of LA(k)
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase, Loyc.LLParserGenerator.GeneralCodeGenHelper, and Loyc.LLParserGenerator.IntStreamCodeGenHelper.
LNode Loyc.LLParserGenerator.IPGCodeGenHelper.MakeInitializedVarDecl | ( | LNode | type, |
bool | wantList, | ||
Symbol | varName | ||
) |
Gets a variable declaration for the specified type, e.g. if type is Foo
and wantList == true
and varName.Name == "x"
, the statement returned might be List<Foo> x = new List<Foo>();
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
IPGTerminalSet Loyc.LLParserGenerator.IPGCodeGenHelper.Optimize | ( | IPGTerminalSet | set, |
IPGTerminalSet | dontcare | ||
) |
Simplifies the specified set, if possible, so that GenerateTest() can generate simpler code for an if-else chain in a prediction tree.
set | |
dontcare | A set of terminals that have been ruled out, i.e. it is already known that the lookahead value is not in this set. |
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase, and Loyc.LLParserGenerator.IntStreamCodeGenHelper.
Returns the node for an alias. If the specified node is not an alias, returns the same node unchanged.
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
bool Loyc.LLParserGenerator.IPGCodeGenHelper.ShouldGenerateSwitch | ( | IPGTerminalSet[] | branchSets, |
MSet< int > | casesToInclude, | ||
bool | hasErrorBranch | ||
) |
Returns true if a "switch" statement is the preferable code generation technique rather than the default if-else chain
branchSets | Non-overlapping terminal sets, one set for each branch of the prediction tree. |
casesToInclude | To this set, this method should add the indexes of branches for which case labels should be generated, e.g. adding index 2 means that switch cases should be generated for sets[2]. The caller (LLParserGenerator) will create an if-else chain for all branches that are not added to casesToInclude, and this chain will be passed to GenerateSwitch. |
Using a switch() statement can be important for performance, since the compiler may be able to implement a switch statement using as little as a single branch, unlike an if-else chain which often requires multiple branches.
However, it does not always make sense to use switch(), and when it does make sense, it may not be wise or possible to include all cases in the switch, so this method is needed to make the decision.
Consider an example with four branches, each having a character set, plus an error branch:
Branch 1: '*'|'+'|'-'|'/'|''|'^'|'&'|','|'|' Branch 2: '_'|'$'|'a'..'z'|'A'..'Z'|128..65535 Branch 3: '0'..'9' Branch 4: ' '|'' Error: anything else
In this case, it is impossible (well, quite impractical) to use cases for all of Branch 2. The most sensible switch() statement probably looks like this:
switch(la0) { case '*': case '+': case '-': case '/': case '': case '^': case '&': case ',': case '|': // branch 1 case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': // branch 3 case ' ': case '': // branch 4 default: if (la0 >= 'A' && la0 <= 'Z' || la0 >= 'a' && la0 <= 'z' || la0 >= 128 && la0 <= 65536) // branch 2 else // error }
Please note that given LLLPG's current design, it is not possible to "split" a branch. For example, the switch cannot include "case '_': case '$':" and use this to handle branch 2 (but not the error case), while also handling branch 2 in the "default" case. Although LLLPG has a mechanism to duplicate branches of an Alts so that the code for handling an alternative is located at two different places in a prediction tree (using 'goto' if necessary), it does not have a similar mechanism for arbitrary subtrees of a prediction tree.
'sets' does not include the error branch, if any. If there's no error branch, the last case should be left out of 'casesToInclude' so that there will be a 'default:' case. Note: it should always be the last set that is left out, because that will be the official default branch (the user can control which branch is default, hence which one comes last, using the 'default' keyword in the grammar DSL.)
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
LNode Loyc.LLParserGenerator.IPGCodeGenHelper.VisitInput | ( | LNode | stmt, |
IMessageSink | sink | ||
) |
In case the IPGCodeGenHelper is interested, the LLLPG macro calls this method on each statement in the body of the macro (as a preprocessing step, before LLLPG looks at it). No action is required.
Implemented in Loyc.LLParserGenerator.CodeGenHelperBase.
|
get |
Returns an empty set of the appropriate type for the kind of parser being generated by this code.
|
get |
Type of variables auto-declared when you use labels in your grammar (e.g. x:Foo (list+:Bar)*)