1
"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 检测为关键字,而是将其检测为 ident。我一直在思考这个问题,但无法解决。有没有人有任何想法?谢谢!

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

4

2 回答 2

1

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

假设我们有一种类似于 Lua 的语言,其中a.b的语法糖是a["b"]. 此外,由于.后面必须跟一个词法标识符——换句话说,它后面永远不会跟一个句法关键字——我们想在这种情况下禁止关键字识别。

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

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

%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");
于 2015-03-22T00:37:24.530 回答
0

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

进行词法分析时,让词法分析器询问解析器接下来期望的标记集。'end' 的 keywork reconizer 询问解析器,它要么“期望 'end'”,词法分析器在哪个指针上简单地处理 'end' 词素,或者它说“期望 ID”,此时它交给解析器名称文本为“end”的 ID。

让您的解析器执行此操作可能会也可能不方便。但是你需要这样的东西。

我们使用 GLR 解析器;我们的解析器在同一个地方接受多个标记。我们的解决方案是生成“end”关键字和带有文本“end”的标识符,并将它们都推送到 GLR 解析器中。可以处理局部歧义;由这种情况引起的多次解析一直持续到假设错误的解析器遇到语法错误,然后它就消失了。最后一个常设的解析器是具有正确假设的解析器。这个方案有点像第一个方案,只是我们将选择交给解析器并由它决定,而不是让词法分析器决定。

您可能能够向您的解析器发送“双重解释”词位,例如,上下文中的关键字词位,它本质上声称它既是关键字又是标识符。在内部使用单个标记前瞻,解析器可能很容易做出决定并重新标记词位。不像 GLR 解决方案那样通用,但可能在很多情况下都有效。

于 2015-03-21T23:13:37.367 回答