pt3dNyc
pt3dNyc

Reputation: 369

boost::spirit::qi difference parser behavior

I'm trying to understand the behavior of Qi's Difference Parsers.

With something like this:

ruleA = 
  ruleAa
| ruleAb
| ruleAc
;

ruleB =
ruleA - ruleAc
;

I was imagining that the parser would match ruleB iff the input matches ruleAa or ruleAb. In other words, ruleB would subtract one alternative (ruleAc) from ruleA. Is this incorrect?

In my code, I'm doing something like the above and it compiles but does not seem to behave as I expected. My actual use-case involves other factors that are hard to unwind here.

In essence, what I'm trying to do is this: I have a rule like ruleA, which contains a set of alternatives. This rule gets used in a few different places in my grammar. But in one particular use, I need to avoid evoking just one of the alternatives. It seems like the difference parser is intended for that purpose, but maybe I'm misunderstanding?

Thanks in advance!

Upvotes: 1

Views: 60

Answers (1)

sehe
sehe

Reputation: 393809

I was imagining that the parser would match ruleB iff the input matches ruleAa or ruleAb. In other words, ruleB would subtract one alternative (ruleAc) from ruleA. Is this incorrect?

(A|B|C) - C is only equivalent to (A|B) iff C never matches anything that (A|B) would match.

A a simple example, assume:

A = int_;
B = +space;
C = char_;

Because C always matches where A or B would match, it is clear that doing (A|B) - C always results in no match. Same for (A|B|C)-C.

In short any A or B that also matches C no longer matches with something - C.


This rule gets used in a few different places in my grammar. But in one particular use, I need to avoid evoking just one of the alternatives. It seems like the difference parser is intended for that purpose

As you've seen above, this is not the case. The difference parser doesn't /modify/ the left-hand-side parser at all. (It just discards some matches independent of the left-hand-side).

The best thing I can think of is to /just use/ (A|B) in one place, and (A|B|C) in the other. It's really that simple: Say What You Mean.

Upvotes: 1

Related Questions