0

I'm trying to build a parser for a DSL I'm building using Irony in .NET and found a problem I can't find a way around. Since it handles BNF I think that any BNF solution will be of help.

I have the following input:

$10 yesterday at drug store 

With the following grammar:

<expr> :== unit | expr + unit
<unit> :==  money | date | location

<date> : == yesterday|today|tomorrow
<location> :== .* | <preposition> .*
<preposition> :== at
<money> :== ((\$)?\d*((\.*)\d*)*\,?\d{1,2})

It works like a charm with this input. I get exactly the result I wanted which is:

Money Amount: 10
Date: Yesterday
Location: Drug Store

However, if I change the order of the input as following

$10 at drug store yesterday

because of reduce steps it fails to give me the same output. The output becomes:

Money amount: 10
Location: Drug Store Yesterday

I was wondering if there is way to make sure that Location (which is a really broad regex match) is only evaluated when all the other tokens are captured and nothing else is left.

Any help is appreciated.

Thanks!

Edit: Updated title according to suggestion

tucaz
  • 6,524
  • 6
  • 37
  • 60
  • This isn't really a question about BNF, per se. In a BNF grammar, there is no concept of "precedence" of rules. What you have is an ambiguous grammar; that is, there is more than one derivation of some strings in your language. The only BNF-centric way to fix this is to come up with a grammar that is unambiguous, and this is not always possible. In your case, the obvious way to try to get an unambiguous grammar is to define so that strings containing things like "yesterday" are caught and not accepted as valid locations. – Patrick87 Aug 17 '11 at 21:00
  • Thanks @Patrick87 for the comment. Assuming that I have more than just yesterday to "ignore" in definition, how do you suggest I do it? Is there a way to say "match this and exclude all that"? – tucaz Aug 17 '11 at 21:04
  • There are easy ways and hard ways to do it; the easy ways depend on capabilities of your regex syntax, and the hard ways work for any regular expressions but, well, take some work to do. You should check your regex syntax for operators/operations like "set difference/except", "union", "intersection", "complement", etc. If you can do this, it's easy; otherwise, you'll need to sit down, construct a DFA accepting the strings you want to reject, construct the complement DFA, and then make a regex based on this. Some automated tools may exist to make this process less painful. – Patrick87 Aug 17 '11 at 21:21
  • I will look into it @Patrick87. Thanks again. But, in my ignorance, since the grammar is ambiguous, shouldn't be a way to get from the parser all answers and then, let my program decide which one is a best fit? – tucaz Aug 17 '11 at 21:30

1 Answers1

-1

Besides the fact that this is not a general answer to BNF ambiguity I was able to solve my problem with Irony by creating a new Terminal.

So if anyone else encounters this problem, the code for the new Terminal (while not added to main Irony project) can be found in this link: http://irony.codeplex.com/discussions/269483

Thanks

tucaz
  • 6,524
  • 6
  • 37
  • 60