2015-01-03 44 views
1

我的語法文件test.ebnf樣子,最新詞彙元素成片

start = identifier ; 

identifier = 
    /[a-z]*/ rest; 

rest = /[0-9]*/ ; 

當我運行這個語法在輸入「test1234」,我希望它產生「test1234」作爲一個單一的語義,而是將AST的樣子,

AST: 
['test', '1234'] 

我試着與nameguard功能設置爲false,沒有運氣運行。如何在不編寫像identifier = /[a-z]*[0-9]*/這樣的規則的情況下獲得此行爲?

回答

1

Grako將總是返回一個列表,每個元素在規則的右側有一個對象,除非只有一個元素。即使在命名元素時,具有相同名稱的多個匹配也會返回一個列表。只是連接元素是不合理的,因爲它們的AST可能是項目所需的複雜對象。

在你的情況,你可以使用一個語義動作加入identifier部分:

def identifier(self, ast): 
    return ''.join(ast) 

或重新定義identifier規則有一個單一的元素:

identifier 
    = 
    /[a-z]+[0-9]*|[a-z]*[0-9]+/ 
    ; 

(注意變化正則表達式,因此它永遠不會匹配空字符串)。

+0

謝謝。儘管如此,我決定在這裏使用語義操作。我不認爲這個邏輯屬於一個語義行爲,看到詞彙規則並且沒有意識到他們正在被另一個文件中的語義行爲在詞彙層面上震撼是令人驚訝的。將來通過現有示例添加規則時,將不清楚如何獲得相同的行爲。是不是有一種方法來命名subregex的,所以我可以打破複雜的詞彙元素,而不必爲語義操作添加黑客。我在Lex裏有這個功能! –

+0

解析規則的結果完全是語義/語義操作的責任。只是碰巧有默認語義,這些語義很好地被指定。默認結果是[解析樹](http://en.wikipedia.org/wiki/Parse_tree),其中右側的序列表示爲列表。命名和語義操作將創建[抽象語法樹](http://en.wikipedia.org/wiki/Abstract_syntax_tree)。這在解析器生成器中幾乎是標準的,但** Grako **的策略是不要用語義來污染語法。 – Apalala

+0

有沒有辦法來命名正則表達式的部分重用?如果我可以說rule =/[a-z] SOME_RE [0-9] /其中SOME_RE是一個正則表達式,我可以在Flex中這樣做會非常有幫助。 –