1

I am using ANTLR 3 to parse and rewrite Answer-Set Programs (ASP). What I want to do is parse an ASP program and output an AST with some rewriting. I can easily add and remove nodes to/from the AST but what I need to do is add nodes to the root dynamically (effectively, adding new rules to the ASP program). Which nodes to add and how many is based on the input ASP program.

Below I have an example from my lexer and parser which outputs an AST. r_rule returns a LinkedHashMap that is filled based on what it matches. For each member of the LinkedHashMap, in the rewrite for r_program I want to add a new node to the root node PROGRAM. However, I cannot seem to find a way to iterate through the LinkedHashMap and add new nodes.

@members {
    int rID = 0;
}

r_program
  : (a=r_rule)* -> ^(PROGRAM r_rule*);

r_rule returns [LinkedHashMap<String, String> somehm]
@init {
    $somehm = new LinkedHashMap<String, String>();
    String strrID = Integer.toString(++rID);
}
: (head = r_head) ':-'
body=r_body[strrID] {$vartypes.putAll($body.vartypes); } -> ^(LIMPL $head ^(EXTENSION     ^(NUMBER[strrID] $head)) $body);

I can use a semantic predicate but only to check a property of the LinkedHashMap. I can arbitrarily loop through the HashMap with inserted code, but I can't then, for each iteration, add child nodes or trigger a rewrite. The code generated is in fact put in the wrong place to even do this in an ugly way using Java (I can't access the root node PARENT).

What can I do about this? A completely different approach is also welcome. Many thanks!

Update 1

An example input is:

head_pred(X, Y, Z) :- body_1(X), body_1(Y), body_1(Z).

An example AST is, apologies for the drawing (n.b. strictly an example used for readability, in reality many more nodes are used in the rewrite)...

PROGRAM
 |
 |____:-
 |    |____head_pred(X, Y, X)
 |    |____body_1(X)
 |    |____body_1(Y)
 |    |____body_1(Z)
 |    |____X == Y
 |
 |____:-
 |    |____head_pred(X, Y, X)
 |    |____body_1(X)
 |    |____body_1(Y)
 |    |____body_1(Z)
 |    |____X == Z

I could go on, the idea is that each rule binds the variables differently, if they can be bound. Different inputs change the number and content of the children of PROGRAM.

Dr. Thomas C. King
  • 993
  • 2
  • 15
  • 28
  • 1
    A better option would be to let `r_rule` return a plain ANTLR tree node instead of a Java `Map`. Could you provide some example input and desired AST? – Bart Kiers Jan 13 '15 at 16:30
  • Thanks Bart, I've added an example input and output. I will now look at dynamically creating an ANTLR tree node in Java and seeing how I can use that. – Dr. Thomas C. King Jan 13 '15 at 16:45
  • Hmm, looking at your update, I'm not sure if my suggestion is helpful. – Bart Kiers Jan 13 '15 at 19:18
  • 1
    Trying to cram this type of tree rewriting inside the grammar itself would probably result in the grammar file containing more Java code than ANTLR rules. I think I'd go for getting a simple AST from ANTLR and then transform that with plain Java code elsewhere. – Bart Kiers Jan 13 '15 at 19:24

0 Answers0