2015-07-19 54 views
0

我使用Jison爲大專以上的項目,我需要做出switch每個識別的標記,這樣我就可以呈現給教授是這樣的:如何在Jison中獲得代幣?

<identifier, s> 
<operator, => 
<identifier, a> 
<operator, +> 
<identifier, b> 

關於如何得到這個沒有做任何方式重複到正則表達式手動? (我的意思是,Jison使用正則表達式內部,但是這不是我的事)

我試圖做的是以下幾點:

var lex = parser.lexer, 
    token; 
lex.setInput('The code to parse'); 
while (!lex.done) { 
    token = lex.next(); 
} 

但我得到保存在token的僅僅是一個數字,當符號沒有在語法中定義,它返回逐個字符的標記。

在此先感謝。

回答

0

(錯誤:此答案是通過檢查由jison生成的代碼衍生自接口沒有很好地定義,也可以不經得起時間考驗。)

parser.lexer.next()不是記錄詞法分析器的一部分接口,雖然由jison生成的詞法分析器似乎實現了它。請注意,如果消耗的輸入對應於不產生令牌的詞法規則,則不會生成令牌。 (例如,忽略空格的規則)。最好使用記錄的接口parser.lexer.lex(),它始終生成一個令牌。

嚴格地說,parser.lexer.lex()記錄爲返回的終端的名稱,但對效率由jison產生的詞法分析器將返回內部數值代碼爲終端如果jison是能夠找出詞彙規則將返回哪個終端。所以,你有幾個選擇,如果你想跟蹤識別的終端的實際名稱:

  1. 您可以通過避免使用形式return <string>的戰勝這種優化。例如,如果你改變了詞法規則:

    [A-Za-z][A-Za-z0-9] { return 'IDENTIFIER`; } 
    

    [A-Za-z][A-Za-z0-9] { return '' + 'IDENTIFIER`; } 
    

    然後將生成的詞法分析器將返回字符串'IDENTIFIER',而不是一些數字代碼。

  2. 或者,您可以使用parser.terminals_根據生成的解析器頂部的註釋具有形式terminals_: {associative list: number ==> name}來查找給定令牌編號的終端名稱。

要獲取與詞位關聯的源字符串,請使用parser.lexer.yytext

下面是使用第二個替代的解決方案:

/* To reduce confusion, I change 'lex' to 'lexer' */ 
var lexer = parser.lexer, 
    token; 
lexer.setInput('The code to parse'); 
while (!lexer.done) { 
    token = lexer.lex(); 
    /* Look up the token name if necessary */ 
    if (token in parser.terminals_) { 
     token = parser.terminals_[token]; 
    } 
    console.log('<' + token + ', ' + lexer.yytext + '>') 
} 
+0

感謝您的回答。我還必須查看生成的解析器源代碼才能發現,Jison文檔仍然有點不足。 順便說一句我用你的形式:) – bryanjhv