Pass Dynamic values to the rules in ANTLR4 grammar - antlr4

I am newbie to ANTLR4
I want to write a grammar that would parse the syntax using the values which it reads dynamically.
Say my grammar is as follows in image
I need help such the HANDLERID not only takes the values mentioned,but a list of values based on a function call,dynamic values. For example a function return list containing {'ACD','GHY','XYZ' ..}. Not to confuse with identifier,these values are names of some defined set of objects, so writing a grammar for IDENTIFIER is not solution.
Any help is appeciated.

Maybe actions are a viable solution? These are written in the target language and allow to do all kind of processing. Formulated as a predicate (appending a ? to the action block) they can even be used to guide the parser what path to take.
Here's a typical form:
decl: type ID ';' { System.out.println("found a decl"); };
or as a predicate:
HANDLERID: ID { isSpecialWord($ID.text) }?;
which will only be matched for IDs that your internal function isSpecialWord is returning true for. So essentially, you are not passing the lexer rule some values, but you do the evaluation in internal code.

Related

How can I pass a structure down a tree (i.e. an inherited attribute) when using Visitor pattern?

I'm using the C++ version of ANTLR4 to develop a DSL for a music product. I used to (30 years ago!) do this kind of thing by hand so it's mostly a pleasure to have something like ANTLR, particularly now that I don't have to insert code in the actual grammar definition itself.
I want to do type checking of actual vs formal args in a function call. In the grammar segment below, the 'actualParameter' can return the type of the expression. However, the 'actualParameterList' needs to return an array (say) of these types so that the code for functionCall can compare to the formal parameter list.
If I was handwriting this, the calls to visit or visitChildren would take an extra parameter after context such that I could create a new array at the appropriate place and then have child nodes fill in the details.
I suppose that instead of just calling visitChildren inside the 'visitActualParameterList' I could create the array there and manually call each child rather than just a simple visitChildren but that feels like a hack, and it becomes very sensitive to minor changes in the grammar.
Is there a better approach?
functionCall: Identifier LeftParen actualParameterList? RightParen
;
actualParameterList:
actualParameter anotherActualParameter
;
actualParameter:
expression
;
anotherActualParameter:
Comma actualParameter anotherActualParameter
|
;
You're on the right path. I would suggest something like:
functionCall: Identifier LPAREN actualParameterList RPAREN
;
actualParameterList:
actualParameter (',' actualParameter)*
;
actualParameter:
expression
;
LPAREN : '(';
RPAREN : ')';
Using this, in the Visitor for actualParameterList you can check each child to see if it's of type actualParameterContext and if so, explicitly call Visit on that child, which will get you into your expression evaluation code (presumably handled in the visitor for actualParameter). This alleviates the need, as you say, to just generically visit children. It's very precise when you can check the type like this.
Here's an example of this pattern from my own code (in C# but surely you'll see the pattern in action):
for (int c = 0; c < context.ChildCount; c++)
{
if (context.GetChild(c) is SystemParser.ServerContext) // make sure correct type
{
string serverinfo = Visit(context.GetChild(c)); // visit the specific child and save return value, string in this case
sb.Append(serverinfo); // use result to fill array or do whatever
}
}
Now that you can see the pattern, back to your code. The syntax:
actualParameter (',' actualParameter)*
means that a parameter list has one actualParameter followed by zero or more additional ones with the * operator. I just threw the comma in there for visual clarity.
As you suggest, Visitor is the perfect pattern for this because you can explicitly visit any node you need to. It won't give you an array, but you can fill an array or any other necessary structure with the results of the visiting the children as you saw in the snip from my code. My Visitor returns strings, and I just appended to a StringBuilder. You can use the same pattern to build whatever you need.

Using Roslyn, if I have an IdentifierNameSyntax, can I find the member type it refers to (field, property, method...)

I am attempting to use the Roslyn SDK and StackExchange.Precompilation (thank you!) to implement aspect-oriented programming in C#6. My specific problem right now is, starting with an IdentifierNameSyntax instance, I want to find the "member type" (method, property, field, var, etc.) that the identifier refers to. (How) can this be done?
Background:
The first proof-of-concept I am working on is some good old design-by-contract. I have a NonNullAttribute which can be applied to parameters, properties, or method return values. Along with the attribute there is a class implementing the StackExchange.Precompilation.ICompileModule interface, which on compilation will insert null checks on the marked parameters or return values.
This is the same idea as PostSharp's NonNullAttribute, but the transformation is being done on one of Roslyn's syntax trees, not on an already compiled assembly. It is also similar to Code Contracts, but with a declarative attribute approach, and again operating on syntax trees not IL.
For example, this source code:
[return: NonNull]
public string Capitalize([NonNull] string text) {
return text.ToUpper();
}
will be transformed into this during precompilation:
[return: NonNull]
public string Capitalize([NonNull] string text) {
if (Object.Equals(text, null))
throw new ArgumentNullException(nameof(text));
var result = text.ToUpper();
if (Object.Equals(result, null))
throw new PostconditionFailedException("Result cannot be null.");
return result;
}
(PostconditionFailedException is a custom exception I made to compliment ArgumentException for return values. If there is already something like this in the framework please let me know.)
For properties with this attribute, there would be a similar transformation, but with preconditions and postconditions implemented separately in the set and get accessors, respectively.
The specific reason I need to find the "member type" of an identifier here is for an optimization on implementing postconditions. Note in the post-compilation sample above, the value that would have been returned is stored in a local variable, checked, and then the local is returned. This storage is necessary for transforming return statements that evaluate a method or complex expression, but if the returned expression is just a field or local variable reference, creating that temporary storage local is wasteful.
So, when the return statement is being scanned, I first check if the statement is of the form ReturnKeyword-IdentifierSyntaxToken-SemicolonToken. If so, I then need to check what that identifier refers to, so I avoid that local variable allocation if the referent is a field or var.
Update
For more context, check out the project this is in reference to on GitHub.
You'll need to use SemanticModel.GetSymbolInfo to determine the symbol an identifier binds to.
Use SemanticModel.GetTypeInfo.Type to obtain the TypeInfo and use it to explore the Type

Evaluating boolean expression in a string - Go

I have a boolean expression in string format, example:
name := "Fred"
type := "Person"
I want to evaluate this expression as true or false.
exp := "(name == Fred) && (type == Person)"
Eventually, I would like to be able to execute conditional statements such as:
if (exp) {
...
}
However, from research this is not something Go supports out of the box. I have seen suggestions on using AST to parse and evaluate. But, I am fairly new to go and especially AST, thus not sure how to go about that. Can someone please provide any guidance on how I may go about evaluating a string boolean expression? I have not come across any packages that support this entirely.
The following is true in theory. But since you're using Go if you can use Go syntax then you can use Go's parser and AST. I don't see any code that can evaluate a Go AST at runtime. But you could probably write one that supported the parts you wanted. Then you'd have a Go interpreter.
The following is what you need to do to support any random expression syntax:
You are going to want to lex and parse. Build an AST (Abstract Syntax Tree) in memory. Then evaluate it.
Your tree nodes might be (my Go syntax is way wrong for this):
Scope {Tree {
Assignment { Symbol: "name", Symbol: "_literal_1" }
Assignment { Symbol: "exp", Value: Tree: {
AndOperation { Tree{...}, Tree{...} }
}
}
Etc.
Then your program can traverse your AST directly or you can write it into bytecode form, but that's really only useful if you want it to be smaller and easy to cache for later.

xtext inferrer: multiple entities

I am very new to Xtext/Xtend, therefore apologies in advance if the answer is obvious.
I would like to allow the end-users of my DSL to define a 'filter', that when applied and 'returns' true it means that they want to 'filter out' the given entity of data from consideration.
I want to allow them 2 ways of defining the filter
A) by introspecting the attributes of a given data object and apply basic rules like
if (obj.field1<CURRENT_DATE && obj.field2=="EXPIRED)
{ return true;} else {return false;}
B) by executing a controlled snippet using 'eval' of my host language
In other words, the user would be expected to type into a string/code block a valid
code snippet of the hosting language
I had decided that the easiest way for me support case A) would be to leverage the XBase rules (including expressions/etc)
Therefore I defined filters (mostly copying the ideas from Lorenzo's book)
Filter:
(FilterDSL | FilterCode);
FilterDSL:
'filterDSL' (type=JvmTypeReference)? name=ID
'(' (params+=FullJvmFormalParameter (',' params+=FullJvmFormalParameter)*)? ')'
body=XBlockExpression ;
FilterCode:
'filterCode' (type=JvmTypeReference)? name=ID
'(' (params+=FullJvmFormalParameter (',' params+=FullJvmFormalParameter)*)? ')'
'{'
body=STRING
'}';
Now when trying to implement the Java mapping for my DSL, via the inferrer stub in Xtend -- I am running into multiple problems.
All of them likely indicate that I am missing some fundamental understanding
Problem 1) fl.body is not defined. fl Is of type Filter, not FilterDSL or FilterCode
And I do not understand how to check what type a given instance is of, so that I can access the content of a 'body' feature.
Problem 2) I do not understand where 'body' attribute in the inferrer method is defined and why. Is this part of ECore? (I could not find it)
Problem 3) what's the proper way to allow a user to specify a code block? String seems to be not the right thing as it does not allow multiline
Problem 4) How do I correctly convert a code block into something that is accepted by the 'body' such that it ends up in the generated code.
Problem 5) How do I setup multiple inferrers (as I have more than one thing for which I need the code generated (mostly) by xBase code generator)
Appreciate in advance any suggestions, or pointer to code examples solving similar problems.
As a side observation, Inferrer and its interplay with XBase has sofar been the most confusing and difficult thing to understand.
in general: have a look at the xtend docs at xtend-lang.org
You can do a if (x instanceof Type) or a switch statement with Type guards (see domain model example)
i dont get that question. both your FilterDSL and FilterCode EClasses should have a field+getter/setter named body, FilterCode of type String, FilterDSL of type XBlockExpression. The JvmTypesBuilder add extension methods to JvmOperation called setBody(String) and setBody(XExpression), syntax sugar lets you call body = .... instead of setBody(...)
(btw you can do crtl+click to find out where a thing is defined)
strings are actually multiline
is answered by (2)
you dont need multiple inferrers, you can infer multiple stuff e.g. by calling toClass or toField multiple times for the same input

Suggestion to execute rule expressions

We have a situation where the user will define some set of business rules or expressions. That will be look like,
if(riskvalue <= 100) // condition
notifyObservers() // action
remarks = remarkshistory //expression
if(allowedriskvalue <= riskvalue) //child condition
do something //can be expression or action
else
do some other thing
else
do some thing
We will plan to parse this and save it as a expression with it's type, like condition, expression and action.
We have some set of operands and functions that can be allowed in the rule definition.
Please suggest me some validation techniques to validate the rule definition.
And, I want suggestion that either,
use expression tree to execute the rule expressions?
use any custom rule parser / evaluator?
build the logic in dynamic class using code dom and execute it?
Thanks in advance!!!

Resources