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

时间:2015-03-21 20:06:50

标签: parsing grammar keyword lexer jison

"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语言的编程语言。

2 个答案:

答案 0 :(得分:1)

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

让我们假设我们有一种类似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");

答案 1 :(得分:0)

修改你的解析器,因此它总是知道它接下来要读的是什么(这将是一些令牌集,你可以使用First(x)的概念来计算它,x是任何非终结符。)

当lexing时,让词法分析器向解析器询问接下来会有哪些令牌集。 你的'end'的keywork重新定义器会询问解析器,并且它要么“期望'结束'”指针,lexer只是简单地指向'end'lexeme,或者它说“期待ID”,此时它将解析器交给解析器名称为“end”的ID。

这可能会或可能不方便让解析器执行。但你需要这样的东西。

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

您或许可以向解析器发送“双解释”词汇,例如,关键词在语境中的词汇,其本质上声称它是关键词和/或标识符。在内部使用单个令牌前瞻,解析器可能很容易决定并重新调整lexeme。不像GLR解决方案那样通用,但可能在很多情况下都有效。