I am trying a get semantic predicate to work. This seems straight forward but somehow doesn’t work, based on a boolean condition I need to either execute a rule (which spits out an AST) or just or manually construct one
below is the parser rule.
displayed_column
:
{columnAliases.containsKey($text)}?
=>-> ^(PROPERTY_LIST ^(PROPERTY IDENTIFIER[columnAliases.get($text)]))
| sql_expression
;
I have tried all gated and disambiguating as well but while running through the code, it always goes to the second rule (sql_expression).
Can anyone please help me out ?
Thanks
EDIT:
I just realized that $text is empty while the predicate is running which is why its always matching the second rule. I changed the rule to this and it works
displayed_column
:
sql_expression
-> {columnAliases.containsKey($text)}? ^(PROPERTY_LIST ^(PROPERTY IDENTIFIER[columnAliases.get($text)]))
-> sql_expression
However I ran into a different problem now, I realized that manually constructing the tree will not work, I need to re-run the rule displayed_column again with the new text (value from columnAliases Map), is that possible?
This was my original question
https://stackoverflow.com/questions/14170541/antlr-dynamic-input-stream-modification-during-parsing
Basically I am trying to interactively parse and interpret sql like statments
ex:
select a.b.c from pool;
select min(abc.def[*]) from pool;
Since the column names might be a bit long I have given the user a preference to alias column names (through a different command), for example the user might set a preference and then run his commands
set column_alias a.b.c d;
select d from pool;
Now while parsing I inject the preferences (Map) into the generated parser and I am trying to replace/map the new column back to the original column and then continue interpreting.
Handling it in the parser seemed like the only option to me since I thought it would be difficult to do it the tree grammer since the column spans multiple rules.
I could post the entire grammar but its a bit too long, here is a scaled down version of it
select_stmt:
: 'select' displayed_column 'from' pool
;
displayed_column
: sql_expression
;
sql_expression
: term ( (PLUS^ | MINUS^) term)*
;
term : factor ( (ASTERISK^ | DIVIDE^) factor)*
;
... <more_rules> ...
I am stuck on this, using string template to output a translated statement and then reparse seems like the only option to me, but this would entail rewriting the entire grammar to output templates (right now I have a combined grammar with outputs an AST and a tree grammar that interprets it).
It would be greatly appreciated if someone can tell me way which is less intrusive.
Thanks again.
Instead of storing the strings as values, why not store the actual AST’s in your map? These AST’s can then be injected by wrapping them inside
{…}in your rewrite rule(s).A demo:
Parsing the input:
would result in the following AST:
EDIT
🙁 alas, it is not Serializable.
In that case, you can store the values as strings, and create an AST on the fly using a small helper method
createNameAST(String alias)and inject the AST this method creates:In case you’re using the debugger from ANTLRWorks: it might have an issue with the method
createNameASTbecause it uses aTParser. Create a small test case by hand:and run this all on the command line:
and you’ll get a DOT file that represents the same AST posted earlier.