2011-08-17 75 views
0

我正在尝试为.NET构建一个解析器,使用.NET中的Irony构建,发现一个问题,我无法找到解决办法。既然它处理BNF,我认为任何BNF解决方案都会有所帮助。处理BNF语法中的歧义

我有以下输入:

 
$10 yesterday at drug store 

具有以下语法:

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

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

它的工作原理是与该输入魅力。我得到完全我想要的结果是:

Money Amount: 10 
Date: Yesterday 
Location: Drug Store 

但是,如果我改变输入的顺序,因为减少步骤,它不能给我相同的输出以下

$10 at drug store yesterday 

。输出变为:

Money amount: 10 
Location: Drug Store Yesterday 

我想知道是否有办法确保位置(这是一个非常广泛的正则表达式匹配)时,所有其他标记被捕获并没有别的离开时才计算。

任何帮助表示赞赏。

谢谢!

编辑:根据建议

+0

这是不是一个真正的问题关于BNF本身。在BNF语法中,没有规则的“优先”概念。你有什么是一个模糊的语法;也就是说,您的语言中有一些以上的字符串派生。唯一能以BNF为中心的方法来解决这个问题,就是提出一个毫不含糊的语法,这并不总是可能的。在你的情况下,尝试获得明确语法的显而易见的方法是定义,以便包含诸如“昨天”之类的字符串被捕获并且不被接受为有效位置。 – Patrick87

+0

感谢@ Patrick87的评论。假设我不止昨天在定义中“忽略”,你如何建议我这样做?有没有办法说“匹配并排除所有这些”? – tucaz

+0

有很简单的方法和艰难的方法来做到这一点;简单的方法取决于正则表达式语法的功能,而困难的方式适用于任何正则表达式,但是,需要做一些工作。您应该检查运算符/操作的正则表达式语法,例如“set difference/except”,“union”,“intersection”,“complement”等。如果可以这样做,那很简单;否则,您需要坐下来,构建一个接受要拒绝的字符串的DFA,构建补充DFA,然后基于此创建正则表达式。一些自动化工具可能存在,使这个过程更轻松。 – Patrick87

回答

-1

除了这个事实,这不是一般的回答模棱两可BNF我能够通过创建一个新的终端来解决我的问题反讽更新标题。

因此,如果任何人遇到这样的问题,新的终端的代码(在不添加到主反讽项目)可以在这个环节发现:http://irony.codeplex.com/discussions/269483

感谢