2010-03-17 42 views
1

我建立用於生產環境中的自定義表達式解析器和評估器,以提供一個有限的DSL給用戶的日期數據類型。解析器本身作爲DSL,需要很簡單。解析器將以不支持動態表達式解析的異國語言構建,也沒有任何解析器生成器工具可用。良好語法用於遞歸下降語法分析器LL(1)

我現在的決定是去與LL(1)文法遞歸下降的方法,所以,即使在評估表達可以快速瞭解代碼是如何工作沒有經驗的程序員。

它來處理由幾種數據類型的混合表達式:小數,百分比,字符串和日期。日期格式爲dd/mm/yyyy很容易與一串分割操作混淆。

就是一個很好的解決這個問題?

我自己的解決方案,旨在保持解析器簡單,涉及到一個特殊的符號前綴日期,比方說單引號:

<date> ::= <apostr><digit><digit>/<digit><digit>/<digit><digit><digit><digit> 

<apostr> ::= ' 

<digit> ::= '0'..'9' 
+0

這取決於你想要做更多的事情,爲不常見的項目留下預先修復,例如,如果日期更常用= 1/2/2010來表示分割。 – Hogan 2010-03-18 19:36:59

回答

1

首先,我LL解析器的粉絲,所以我贊成你的方法衷心地。請注意,其中一個較新的流行解析器生成器(ANTLR)是LL。如果你允許更多的前瞻,而不是限制你自己LL(1),你可以做任何你想要用LR(1)解析器做的事情,但是代碼會更清晰,更可靠,並且更易於調試。

我不知道有足夠的瞭解您的整體語法能夠告訴。有可能你可以設計一些東西,這樣LL解析器總是可以從上下文中看出它是一個整型表達式還是一個日期常量。然而,假設你不能,是的,你需要某種方式來區分差異。我唯一能想到的其他事情就是使用反斜槓作爲分隔符而不是斜槓,但這有點難看。

+0

T.E.D謝謝,感謝!例如,在這種情況下,MS Excel將從上下文推斷出該類型,即單元格中的寫入= 01/01/2010將導致0.000497512。但是,顯式或隱式地設置單元格數據類型的日期將處理一個日期。但是我覺得這種類型推斷魔術會給解析器評估器增加很多複雜性,並且可能會混淆負責維護解析器的用戶和程序員(根據他們以前沒有用過解析器的假設)。 – 2010-03-17 14:05:05

1

的LL-像lexerless具有無限前瞻解析器是你所需要的。而且,也就是PEG。

http://en.wikipedia.org/wiki/Parsing_expression_grammar

有了一個有序的選擇,這是很容易避免這個日期與常量文字分工混亂。

+0

我也會認爲有序選擇是最乾淨的(也可能是唯一的)解決方案。 – 2010-03-18 00:24:52

+0

我不太確定。在某些情況下,他的語法很可能不明確,但在日期前沒有添加撇號。 PEG是強大的,但它們不能處理模糊的語法。 – 2010-03-18 16:28:47

+0

他們可以解決歧義。如果東西看起來像日期,那麼它首先被解析,作爲日期。如果那麼它被用在預期會有其他事情的環境中,它就會被回溯並以另一種方式進行修復。例如,1/2/3將是日期,但是1/2/3/4將是1除以2除以3等。 – 2010-03-18 17:43:09

0

當一種語言旨在用於人類輸入,其定義是儘可能多的

  • 事項添加語法限制,以確保明確且容易解析
  • 去除/彎曲的語法,以確保語言感覺直觀,「自然」,以適應預期的人類觀衆。

滿足第二要求是比第一次更難,需要洞察語言
哪種類型的鍵盤/輸入設備的可用的

  • 預期使用情況?在允許的字符中是否有一些字符難以製作或在顯示屏上看到?
    哪些令牌/表達式會被頻繁使用,哪些只會偶爾需要? 是否用戶經常輸入短,即席代碼片段,或意味着該計劃被重用和修改在長期內
    ...等
  • 目標受衆的
  • 背景/文化
    哪些常見的做法/成語從其他常規(和普通的自然語言)語言可以或應該重用,如果可能的話?
    應該有人贊成一種簡潔而含蓄的風格,或者更明確,但更冗長的風格?
    ...等

基本上,這是很難做出一個語言的語法的建議,不使用目的和用戶把握好。
不過,我想建議的日期格式問題如下:

使用日期值完全另一種格式;一個對用戶而言「足夠自然」,但足夠與正規語法描述的區別。
例如,一個使用月份的3個字母縮寫(下行DSL與英語或其他語言聯繫在一起,但也有優勢,對於人類而言,這是對白天和月份的模糊性被刪除)。姑且:

dd-mmm-yyyy (may seem unnatural in cultures where the prevailing date order 
        starts with the month maybe yyyy-mmm-dd then ?) 
    mmm-dd-yyyy (better for the above mentioned cultures) 
    ddmmmyyyy  (avoid the dashes, but impose leading zeros) 

    MnnDnnYyyyy (using "M", "D" and "Y" (or others) as explicit prefixes; now, 
        this is completely culture neutral, but maybe a bit awkward...) 

反正只是想法......適用性將提到,與語法的其他人/文化因素而有所不同。例如,上述可能意味着變量被明確地標記(這是許多語言使用$前綴的原因之一),以避免與[奇怪但可能的]變量標識符可能的衝突。

簡而言之,這個想法是用一個特殊的字符前綴(它可能會碰撞使用這些字符的數學表達式和其他表達式),通過使12個月的標籤足夠好的判別器來解析器。