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
我想知道是否有辦法確保位置(這是一個非常廣泛的正則表達式匹配)時,所有其他標記被捕獲並沒有別的離開時才計算。
任何幫助表示讚賞。
謝謝!
編輯:根據建議
這是不是一個真正的問題關於BNF本身。在BNF語法中,沒有規則的「優先」概念。你有什麼是一個模糊的語法;也就是說,您的語言中有一些以上的字符串派生。唯一能以BNF爲中心的方法來解決這個問題,就是提出一個毫不含糊的語法,這並不總是可能的。在你的情況下,嘗試獲得明確語法的顯而易見的方法是定義,以便包含諸如「昨天」之類的字符串被捕獲並且不被接受爲有效位置。 –
Patrick87
感謝@ Patrick87的評論。假設我不止昨天在定義中「忽略」,你如何建議我這樣做?有沒有辦法說「匹配並排除所有這些」? –
tucaz
有很簡單的方法和艱難的方法來做到這一點;簡單的方法取決於正則表達式語法的功能,而困難的方式適用於任何正則表達式,但是,需要做一些工作。您應該檢查運算符/操作的正則表達式語法,例如「set difference/except」,「union」,「intersection」,「complement」等。如果可以這樣做,那很簡單;否則,您需要坐下來,構建一個接受要拒絕的字符串的DFA,構建補充DFA,然後基於此創建正則表達式。一些自動化工具可能存在,使這個過程更輕鬆。 – Patrick87