当前位置: 代码迷 >> JavaScript >> 如何在Jison中获取令牌?
  详细解决方案

如何在Jison中获取令牌?

热度:99   发布时间:2023-06-13 12:45:17.0

我正在使用Jison进行大学项目,并且需要为每个已识别的标记进行switch ,因此我可以向教授介绍以下内容:

<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的唯一一件事是一个数字,并且当语法中未定义符号时,它会返回每个字符的令牌。

提前致谢。

(警告:部分答案是通过检查jison生成的代码得出的。由于接口的定义不明确,因此可能无法经受时间的考验。)

尽管jison生成的词法分析器确实实现了它,但parser.lexer.next()并非已记录的词法分析器接口的一部分。 请注意,如果消耗的输入对应于不产生标记的词法规则,则它不会产生标记。 (例如,忽略空格的规则。)最好使用记录的接口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} ,以查找给定令牌编号的终端名称。

要获取与lexeme关联的源字符串,请使用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 + '>')
}
  相关解决方案