Return value from subtree possible?

52 views
Skip to first unread message

Christian Wolf

unread,
Sep 26, 2014, 3:31:56 AM9/26/14
to sab...@googlegroups.com
Hello everyone,

I have the following issue:
I want to use SableCC to parse a string that represents some boolean filtering expression. I have already created classes that represent the different filtering constraints (e.g. Username is equal to given string,...) as well as the basic boolean operations AND, OR and NOT.
The question is now: Is it possible to add a return value to the production rules in some (intelligent) way?

To clarify take the example that I had the tokens int, leq, geq, equal and owner_id. We want to formulate a filter on the (numeric) owner_id.
Next assume the production rules as following:
> filter_total = ... | {owner} owner_filter | ... ;
> owner_filter = {equal} owner_id equal int | {leq} owner_id leq int | {geq} owner_id geq int;
The result is there is created a (abstract) POwnerFilter class and two times three methods are generated in the DepthFirstAdapter: (both in and out versions of) *AEqualOwnerFilter, *ALeqOwnerFilter and *AGeqOwnerFilter. Further there is two methods *AOwnerFilterTotal(POwnerFilter node). I can access the child node of type POwnerFilter using node.getOwnerFilter but that is a abstract class which does not know anything of the underlying structures.
This is clear, as statically we only know that a owner_filter can be read. Which exact type is not known at compile time and therefore this is clear.
In the different *A*OwnerFilter methods I can access the content of the explicit values (in this case the IDs). Thus I can create a filter class as already implemented.
The problem is: How to return this filter object to the parent production rule? That is: How to access the created object in outAEqualOwnerFilter in e.g. outAOwnerFilterTotal?

The best solution would be (in my opinion) to allow a object (or multiple) to be attached to the abstract class POwnerFilter but this means that I would have to alter the generated classes by sablecc. On regeneration/reinvocation all modifications will be lost.
The alternative is to use a pure implementation based on DepthFirstAdapter. In this case I have to do some "magic" with stacks to allow recursive expressions like ((a AND b) OR (c AND NOT d)) AND e (to avoid the outer AND does not get confused by the inner one).

Do you see any better structure?

Thanks a lot
Christian

Etienne Gagnon

unread,
Sep 30, 2014, 2:43:39 PM9/30/14
to sab...@googlegroups.com
Hi Christian,

You should read my reply to a previous post for a simple/nicer technique: https://groups.google.com/d/msg/sablecc/gtZ5EmDRUl8/d72F4TScpD0J

The idea is that you don't store the value with the node; you store the current result value in an instance variable of the visitor class.

Something like:

public class Evaluator extends DepthFirstAdaptor {

  private boolean result;

  private boolean eval(Node node) {
    node.apply(this);
    return result;
  }

  @Override
  public void caseAEqualOwnerFilter(AEqualOwnerFilter node) {
    ...
    this.result = ...;
  }
  ...
  @Override
  public void caseAAndExp(AAndExp node) {
    boolean left = eval(node.getLeft());
    boolean right = eval(node.getRight());
    this.result = left && right;
  }
  ...
}
Have fun!

Etienne

Etienne Gagnon, Ph.D.
http://sablecc.org
--
-- You received this message because you are subscribed to the SableCC group. To post to this group, send email to sab...@googlegroups.com. To unsubscribe from this group, send email to sablecc+u...@googlegroups.com. For more options, visit this group at https://groups.google.com/d/forum/sablecc?hl=en
---
You received this message because you are subscribed to the Google Groups "SableCC" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sablecc+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages