(警告:部分答案是通过检查 jison 生成的代码得出的。由于接口定义不明确,可能经不起时间的考验。)
parser.lexer.next()
不是记录在案的词法分析器接口的一部分,尽管 jison 生成的词法分析器似乎确实实现了它。请注意,如果所使用的输入对应于不产生令牌的词法规则,则它不会产生令牌。(例如,忽略空格的规则。)最好使用记录在案的 interface parser.lexer.lex()
,它总是会产生一个标记。
严格来说,parser.lexer.lex()
记录为返回终端的名称,但为了提高效率,jison 生成的词法分析器将返回终端的内部数字代码,如果jison
能够确定词法规则将返回哪个终端。因此,如果您想跟踪识别的终端的实际名称,您有几个选择:
您可以通过避免使用 form 来破坏这种优化return <string>
。例如,如果您更改词法规则:
[A-Za-z][A-Za-z0-9] { return 'IDENTIFIER`; }
至
[A-Za-z][A-Za-z0-9] { return '' + 'IDENTIFIER`; }
然后生成的词法分析器将返回字符串'IDENTIFIER'
而不是一些数字代码。
或者,您可以使用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 + '>')
}