Jison Lexer语言 - 在特定时间检测某些关键字作为标识符


"end"  { return 'END'; }
...
0[xX][0-9a-fA-F]+ { return 'NUMBER'; }
[A-Za-z_$][A-Za-z0-9_$]* { return 'IDENT'; }
...
Call
  : IDENT ArgumentList
    {{ $$ = ['CallExpr', $1, $2]; }}
  | IDENT
    {{ $$ = ['CallExprNoArgs', $1]; }}
  ;
CallArray
  : CallElement
    {{ $$  = ['CallArray', $1]; }}
  ;
CallElement
  : CallElement "." Call
     {{ $$ = ['CallElement', $1, $3]; }}
  | Call
  ;

你好!所以,在我的语法中,我希望"res.end((;"不检测 end 作为关键字,而是检测为标识。我已经考虑了一段时间,但无法解决。有人有什么想法吗?谢谢!

编辑:这是一种类似C的编程语言。

问题中没有足够的信息来证明我在这里所做的假设,所以这个答案可能不准确。

假设我们有一种有点类似Lua的语言,其中a.ba["b"]的句法糖。此外,由于 . 必须后跟一个词法标识符 - 换句话说,它永远不会跟有句法关键字 - 我们希望在此上下文中禁止关键字识别。

这是一个非常简单的规则。它非常简单,词法分析器可以在没有任何语义信息的情况下实现它;它所说的只是 . 后面的令牌必须是标识符。在这种情况下,关键字应被视为标识符,标识符以外的任何其他内容都是错误。

我们可以在启动条件下做到这一点。具体来说,我们定义了一个仅在 . 令牌之后使用的开始条件:

%x selector
%%
/* White space and comment rules need to explicitly include
 * the selector condition
 */
<INITIAL,selector>s+   ;
/* Other rules, including keywords, are unmodified */
"end"                   return "END";
/* The dot rule triggers a new start condition */
"."                     this.begin("selector"); return ".";
/* Outside of the start condition, identifiers don't change state. */
[A-Za-z_]w*            yylval = yytext; return "ID";
/* Only identifiers are valid in this start condition, and if found
 * the start condition is changed back. Anything else is an error.
 */
<selector>[A-Za-z_]w*  yylval = yytext; this.popState(); return "ID";
<selector>.             parse_error("Expecting identifier");

修改你的解析器,让它总是知道它接下来要读取什么(这将是一组令牌,你可以使用 First(x( 的概念来计算它,因为 x 是任何非终端(。

进行词法

分析时,让词法分析器询问解析器接下来需要哪组标记。"end"的键工作协调器会询问解析器,它要么以"期望'end'"的方式"期望'end'",词法分析器只是在'end'词法上交出哪个指针,要么说"期望ID",此时它会向解析器递给一个名称文本为"end"的ID。

这可能方便也可能不方便让你的解析器做。 但是你需要这样的东西。

我们使用 GLR 解析器;我们的解析器在同一位置接受多个令牌。 我们的解决方案是生成"end"关键字和带有文本"end"的标识符,并将它们都塞入GLR解析器中。 它可以处理局部歧义;由此引起的多次解析继续进行,直到具有错误假设的解析器遇到语法错误,然后它就会消失,通过命令。 最后一个常设解析器是具有正确假设集的解析器。 这个方案有点像第一个方案,只是我们把选择交给解析器,它决定而不是让词法分析器决定。

你也许可以向解析器发送一个"双解释"词法,例如,一个上下文中的关键字词法,它本质上声称它既是关键字又是标识符。 通过内部的单个令牌前瞻,解析器可能可以轻松决定并重新标记词法。 不像 GLR 解决方案那样通用,但可能在很多情况下都有效。

相关内容

  • 没有找到相关文章

最新更新