2015-07-19 57 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