2015-07-18 21 views
0

我正在爲Wolfram語言編寫解析器。該語言具有「命名字符」的概念,該命名由由\[]定界的名稱來指定。例如:\[Pi]antlr4:需要將符號序列轉換爲詞法分析器中的字符

假設我想爲一個標識符指定一個正則表達式。標識符可以包含命名字符。我看到了兩種方法:一種是預處理器將所有命名字符轉換爲unicode表示形式,另一種是枚舉所有可能的命名字符作爲正則表達式的一部分。

第二種方法似乎不可行,因爲有很多命名字符。我寧願在我的正則表達式中有unicode字符的範圍。

所以我想預處理我的令牌流。換句話說,在我看來,詞法分析器需要檢查命名字符語法是否正確,然後查找名稱並將其轉換爲unicode。

但是,如果語法不正確或名稱不存在,我需要告訴用戶它。如何將這個錯誤傳播給用戶,然後讓antlr4從錯誤中恢復並恢復?也許我可以排序「管道」詞法分析器/解析器? (我是antlr的新手)。

編輯:

在Wolfram語言我可以具有這個字符串作爲標識符:\[Pi]Squared。括號內的部分稱爲「命名字符」。有一組有限的命名字符,每個命名字符對應一個unicode碼點。我想弄清楚如何標記這樣的標識符。

我可以有我的令牌像這樣(簡化爲一個名爲字符和ASCII字符的組合)的規則:

NAME : ('\\[' [a-z]+ ']'|[a-zA-Z])+ ; 

,但我想,以檢查是否已命名的字符確實存在(和其他屬性,如它是否是一個字母,但後一部分不在問題範圍內),所以這個正則表達式不起作用。

我考慮製作一個允許的命名字符的列表,並且只是列舉一個很長的正則表達式,但這看起來很難看。

這將是一個很好的方法嗎?編輯

回答

1

一種常見的做法

到底是寫詞法分析器/解析器,讓語法正確的輸入和語義問題推遲到生成的解析樹的分析。在這種情況下,詞法分析器可以天真地接受命名字符:

NChar : NCBeg .? RBrack ; 

fragment NCBeg : '\\[' ; 
fragment LBrack: '[' ; 
fragment RBrack: ']' ; 

更新

在解析器,允許NCHAR的在分析樹作爲獨立終端節點存在:

idents : ident+ ; 
ident : NChar // named character string 
     | ID  // simple character string? 
     | Literal // something quoted? 
     | .... 
     ; 

這使分析樹的分析變得相當容易:每個ident上下文將只包含一個非零值用於可離散識別的alt;並將所有訂購問題的分析隔離到idents上下文中。

UPDATE2

對於輸入\[Pi]Squared,解析樹形式將是最簡單的分析將是一個idents節點有兩個秩序井然的孩子,\[Pi]Squared

最好的做法不是將兩個孩子放在同一個標​​記中 - 只需稍後手動將標記文本分爲兩部分以檢查它是否包含有效的命名字符以及部分的特定順序是允許的。

沒有正則表達式將允許確定的命名字符驗證。這將需要一個列表。收緊NCHAR的詞法分析器定義可以,但是,達到相當於一個正則表達式的結果:

NChar : NCBeg [A-Z][A-Za-z]+ RBrack ; 

如果值得關注的是,有可能是已命名的字符後面輸入一個空格,認爲這種情況是有可能更好地處理語義警告,而不是語法錯誤。不要在詞法分析器中跳過空格,而要將空白放在隱藏通道上。然後,在每個idents上下文的驗證分析中,檢查隱藏通道是否存在干擾空白,並根據需要發出警告。

----

然後解析樹遊客可以檢查,驗證,以及關於未知或拼寫錯誤的文字命名警告適當。

做驗證的解析器,如果更爲理想,使用預測性規則來區分未知命名字符稱爲:

@members { 
    ArrayList<String> keyList = .... // list of named chars 

    public boolean inList(String id) { 
     return keyList.contains(id) ; 
    } 
} 

nChar : known 
     | unknown 
     ; 

known : NChar { inList($NChar.getText()) }?    ; 
unknown : NChar { error("Unknown " + $NChar.getText()); } ; 

inList功能可以實現的距離度量來檢測拼寫錯誤,而是糾正直接在分析樹中的文本有點複雜。在訪問者操作過程中作爲分析樹裝飾實施時更容易實現。

最後,將named characters轉換爲可用的映射(包括unicode和ascii)可能是值得處理表示以及轉換和拼寫錯誤的。

+0

謝謝。你的意思是爲標識符標記使用'ID =([a-z] | NChar)+',並在構建分析樹之後檢查指定字符的值? – akonsu

+0

答覆已更新。 – GRosenberg

+0

謝謝。我還沒有看到它會如何幫助我製作符合標識符部分的解析器製作。這隻有在我不跳過空格時纔有效,對吧?也許我完全困惑... – akonsu

相關問題