I'm writing a grammar for a simple language using ANTLR3 C target. I want to attach some data
to the AST generated by ANTLR. As the data to attach is small, using the generic void pointer in ANTLR3_BASE_TREE_struct is quite straightforward. The ANTLR3c documentation states that
void * u
Generic void pointer allows the grammar programmer to attach any structure they like to
a tree node, in many cases saving the need to create their own tree and tree adaptors.
Then I wrote the grammar as below(only a piece of grammar is shown here)
datum
#declarations {
parser_data_t* data;
}
#init{
data = HPS_MALLOC(sizeof(parser_data_t));
HPS_RT_ASSERT(data, HPS_ERR_NOMEM);
}
: simpleDatum
{
data->candidate = 0;
$datum.tree->u = data;
}
-> ^(I_DATUM simpleDatum)
| compoundDatum
{
data->candidate = 1;
$datum.tree->u = data;
}
-> ^(I_DATUM compoundDatum)
;
then I generate the lexer/parser, compiled it and linked it to a main function. When I ran the program, a segment fault occurred. I checked the parser generated by ANTLR and found the problem. The assignment $datum.tree->u = data caused the segment fault because
the data structure $datum.tree hadn't been assigned a valid value, so $datum.tree->u is an invalid reference.
What I want is to attach some data to the tree node representing the non-terminal datum, anyone could tell me how to achieve that? I've searched in google and StackOverflow but no answer found.
Thank you!
Related
Is it possible to generate .m and .h's for any grammar/ rules so that during parsing it creates an object that represents that rule.
So some grammar
coolObjName = Word;
could generate a class that is named coolObjName (or some variation) and has a field for the word, and generates the action:
coolObjName = Word{
CoolObjName* newName = [[CoolObjName alloc] initWithWord:POP_STR()];
PUSH(newName);
};
Then a higher level rule such as:
myhigherlevel = coolObjName Number;
would create a myHigherLevel class that has a coolObjName member and a number, which then adds the action:
myhigherlevel = coolObjName Number{
double num = POP_DOUBLE();
coolObjName* name = POP();
MyHigherLevel* higherLevel = [[MyHigherLevel alloc] init];
higherLevel.number = num;
higherLevel.name = name;
PUSH(higherLevel);
};
Empty tags turn to empty objects and * and + result in arrays.
Is there a tool that can do this or where would I go to create such. (seems super useful and awesome)
Creator of PEGKit here.
There's nothing currently in PEGKit which will inspect your rules and auto-generate ObjC AST or model classes which might match your intent. For now, PEGKit can only produce source code for your parser, but not your related AST or model classes.
It is probably very likely that you will be building an Abstract Syntax Tree (or Intermediate Representation) in your Actions or Parser Delegate Callbacks. ANLTR has some wonderful high-level Tree Rewriting features which allow you to specify in the grammar how to build your AST. Although looking at the docs it seems this might have changed significantly since ANTLR 3? Not sure. It used to look like something like this (maybe it still does, I'm not an ANTLR expert):
addExpr : lhs=NUM op='+' rhs=NUM -> ^(op lhs rhs);
The -> means rewrite to tree like…
And the ^(op …) means tree rooted by a plus operator containing children….
I would love to add tree rewriting features like this to PEGKit, for the express purpose of building ASTs (but not other model objects). But honestly, it's a huge task, and it is not likely to appear soon.
I have a generated grammar that does two things:
Check the syntax of a domain specific language
Evaluate input against that domain specific language
These two functions are separate, lets call them validate() and evaluate().
The validate() function builds the tree from a String input while ensuring it meets the requirements of the BNF for the language. The evaluate() function plugs in values to that tree to get a result (usually true or false).
What the code is currently doing is running validate() each time on the input, just to generate the tree that evaluate() uses. Some of the inputs take up to 60 seconds to be checked. What I would LIKE to do is serialize the results of validate() (assuming it meets the syntax requirements), store the serialized form in the backend database, and just load it from the database as part of evaluate().
I noticed that I can execute the method toStringTree() on the parse tree, and retrieve a LISP style tree. However, can I restore a LISP style tree to an ANTLR parse tree? If not, can anyone recommend another way to serialize and store the generated parse tree?
Thanks for any help.
Jason
ANTLR 4's ParseRuleContext data structure (the specific implementation of ParseTree used by generated parsers to represent grammar rules in the parse tree) is not serializable by default. Open issue #233 on the project issue tracker covers the feature request. However, based on my experience with many applications using ANTLR for parsing, I'm not convinced serializing the parse trees would be useful in the long run. For each problem serializing the parse tree is meant to address, a better solution already exists.
Another option is to store a hash of the last known valid file in the database. After you use the parser to create a parse tree, you could skip the validation step if the input file has the same hash as the last time it was validated. This leverages two aspects of ANTLR 4:
For the same input file, running the parser twice will produce the same parse tree.
The ANTLR 4 parser is extremely fast in almost all cases (e.g. the Java grammar can process around 20MB of source per second). The remaining cases tend to be caused by poorly structured grammar rules that the new parser interpreter feature in ANTLRWorks 2.2 can analyze and make suggestions for improvement.
If you need performance beyond what you get with this, then a parse tree isn't the data structure you should be using. StringTemplate 4's enormous performance advantage over StringTemplate 3 came primarily from the fact that the interpreter switched from using ASTs (equivalent to parse trees for this reasoning) to a linear bytecode representation/interpreter. The ASTs for ST4 would never need to be serialized for performance reasons because the bytecode would be serialized instead. In fact, the C# port of StringTemplate 4 provides exactly this feature.
If the input data to your grammar is made of several independent blocks, you could try to store the string of each block separately, and run the parsing process again for each block independently, using a ThreadPool for example.
Say for example your input data is a set of method declarations:
int add(int a, int b) {
return a+b;
}
int mul(int a, int b) {
return a*b;
}
...
and the grammar is something like:
methodList : methodDeclaration methodList
|
;
methodDeclaration : // your method declaration rules...
The first run of the parser just collects each method text and store it. The parser starts the process at the methodList rule.
void visitMethodList(MethodListContext ctx) {
if(ctx.methodDeclaration() != null) {
String methodStr = formatParseTree(ctx.methodDeclaration(), " ");
// store methodStr for later parsing
}
// visit next method list item, if any
if(ctx.methodList() != null) {
visit(ctx.methodList());
}
}
The second run launch the parsing of each method declaration (in a separate thread for example). For this, the parser starts at the methodDeclaration rule.
void visitMethodDeclaration(MethodDeclarationContext ctx) {
// parse the method block
}
The reason why the text of a methodDeclaration rule is formatted if because calling directly ctx.methodDeclaration().getText() would combine the text of all child nodes AntLR doc, possibly making it unusable for parsing again. If white space is a token separator in the grammar, then adding one space between tokens should not change the parse tree.
String formatParseTree(ParseTree tree, String separator) {
StringBuilder builder = new StringBuilder();
for(int i = 0; i < tree.getChildCount(); i ++) {
ParseTree child = tree.getChild(i);
if(child instanceof TerminalNode) {
builder.append(child.getText());
builder.append(separator);
} else if(child instanceof RuleContext) {
builder.append(formatParseTree(child, separator));
}
}
return builder.toString();
}
How to make your code not compilable if its format does not match some rules?
For example (C# language):
if (a < b)
{
// <-- build error with message "empty line"
k = j + h;
}
or
public void Method(int a, int name) // <-- build error with message "parameter name 'a' is too short"
{
//...
}
If you're looking specifically for C# style-checking, have you tried stylecop?
For a comprehensive list of style-checkers, wikipedia is your friend.
Unless the compiler has specific flags to reject certain types of syntax, you can't make the compiler do that. But you can add a code analysis script that analyzes the source code prior to compiling. You can implement all kinds of coding style rules in that script and it will reject the source code before actually compiling it.
You could have your version control system reject a checkin if it doesn't conform to standards.
Is there a way to convert a MethodBody (or other Reflection technique) into a System.Linq.Expressions.Expression tree?
It is indeed possible, see DelegateDecompiler:
https://github.com/hazzik/DelegateDecompiler
NOTE: I am not affiliated with this project
Edit
Here is the basic approach that the project takes:
Get MethodInfo for the method you want to convert
Use methodInfo.GetMethodBody to get a MethodBody object. This contains,
among other things, the MSIL and info on arguments and locals
Go through the instructions, examine the opcodes, and build the appropriate Expressions
Tie it all together and return an optimized Expression
Here is a code snippet from the project that decompiles a method body:
public class MethodBodyDecompiler
{
readonly IList<Address> args;
readonly VariableInfo[] locals;
readonly MethodInfo method;
public MethodBodyDecompiler(MethodInfo method)
{
this.method = method;
var parameters = method.GetParameters();
if (method.IsStatic)
args = parameters
.Select(p => (Address) Expression.Parameter(p.ParameterType, p.Name))
.ToList();
else
args = new[] {(Address) Expression.Parameter(method.DeclaringType, "this")}
.Union(parameters.Select(p => (Address) Expression.Parameter(p.ParameterType, p.Name)))
.ToList();
var body = method.GetMethodBody();
var addresses = new VariableInfo[body.LocalVariables.Count];
for (int i = 0; i < addresses.Length; i++)
{
addresses[i] = new VariableInfo(body.LocalVariables[i].LocalType);
}
locals = addresses.ToArray();
}
public LambdaExpression Decompile()
{
var instructions = method.GetInstructions();
var ex = Processor.Process(locals, args, instructions.First(), method.ReturnType);
return Expression.Lambda(new OptimizeExpressionVisitor().Visit(ex), args.Select(x => (ParameterExpression) x.Expression));
}
}
No, there isn't.
You're basically asking for a somewhat simpler version of Reflector.
Yes, it is possible... but it hasn't been done yet, as far as I know.
If anyone does know of a library that de-compiles methods to expression trees, please let me know, or edit the above statement.
The most difficult part of what you would have to do is write a CIL de-compiler. That is, you would need to translate the fairly low-level CIL instructions (which conceptually target a stack machine) into much higher-level expressions.
Tools such as Redgate's Reflector or Telerik's JustDecompile do just that, but instead of building expression trees, they display source code; you could say they go one step further, since expression trees are basically still language-agnostic.
Some notable cases where this would get especially tricky:
You would have to deal with cases of CIL instructions for which no pre-defined Expression tree node exists; let's say, tail.call, or cpblk (I'm guessing a little here). That is, you'd have to create custom expression tree node types; having them compiled back into an executable method when you .Compile() the expression tree might be an issue, because the expression tree compiler tries to break down custom nodes into standard nodes. If that is not possible, then you cannot compile the expression tree any more, you could only inspect it.
Would you try to recognise certain high-level constructs, such as a C# using block, and try to build a (custom) expression tree node for it? Remember that C# using breaks down to the equivalent of try…finally { someObj.Dispose(); } during compilation, so that is what you might see instead of using if you reflected over the method body's CIL instructions and exception handling clauses.
Thus, in general, expect that you need to be able to "recognise" certain code patterns and summarise them into a higher-level concept.
I want to generate C code. I will not be reading from an input file, one line at a time (as, for instance, a compiler might). Rather, I will be parsing user input as it arrives, one line at a time.
I would prefer to detect and handle bad input in the lexer/parser, e.g
/* lexer tokens */
foo : "FOO";
bar : "BAR";
baz : "BAZ";
/* grammar*/
grammar : foo "=" BAZ
| foo "=" BAR
| <some non-existent Antrl-else> : {printf(stderr, "bad input\n");}
;
OK, if I can't catch it in the lexer/parser, it seems like I need to use displayRecognitionError() but how??
Can anyone point me at a very simple example which generates C code and shows some error handling of invalid input?
Thanks!
Ok, bounty, yippee!
But only for a real, working answer, with real, working code. No "use method X()" without an wxample.
What you are most likely looking for is the displayRecognitionError() function. This function is called in the cases that you are interested in, and is part of the C runtime.
If you want to see an example of how to use this function, look at this mailing list post. Although this code mixes C and C++, you should be able to work out what you need from it.
Handling a recognition exception in Java would go like this:
grammar X;
// ...
#rulecatch{
catch(RecognitionException rex) {
// do something
}
}
// parser rules
// lexer rules
In other words, simply add some custom C code inside the #rulecatch{ ... } block.