"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语言的编程语言。
答案 0 :(得分:1)
在问题中没有足够的信息来证明我在这里做出的假设是正确的,所以这个答案可能是不准确的。
让我们假设我们有一种类似Lua的语言,其中a.b
是a["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解决方案那样通用,但可能在很多情况下都有效。