我有一个ANTLR JavaScript语法(取自Internet),它似乎支持除正则表达式文字之外的所有内容。
正则表达式文字的问题在于你有两个规则,基本上是:
multiplicativeExpression
: unaryExpression (LT!* ('*' | '/' | '%')^ LT!* unaryExpression)*
和
regexLiteral
: '/' RegexLiteralChar* '/'
其中规则RegexLiteralChar使用不同于正常表达式的词法规则(例如,双引号不会终止它)。
这意味着我需要以某种方式从我的解析器中改变某种词法分析器状态。我怎样才能做到这一点?它甚至可能吗?
答案 0 :(得分:5)
观看Bart Kiers here评论中提到的语法,你可以看到这个评论,
定义这种语法面临的主要挑战是:
-1-与乘法表达式和正则表达式文字相关的DIV符号周围的歧义。这是 用一些lexer驱动的魔法解决:一个门控语义谓词 打开或关闭正则表达式的识别,基于 RegularExpressionsEnabled属性的值。经常 表达式启用后,它们优先于除法 表达式。是否启用正则表达式的决定是 基于前一个令牌可被视为的启发式方法 分裂的左侧操作数的最后一个标记。
...
areRegularExpressionsEnabled()函数定义为,
private final boolean areRegularExpressionsEnabled()
{
if (last == null)
{
return true;
}
switch (last.getType())
{
// identifier
case Identifier:
// literals
case NULL:
case TRUE:
case FALSE:
case THIS:
case OctalIntegerLiteral:
case DecimalLiteral:
case HexIntegerLiteral:
case StringLiteral:
// member access ending
case RBRACK:
// function call or nested expression ending
case RPAREN:
return false;
// otherwise OK
default:
return true;
}
}
然后该函数用于RegularExpressionLiteral表达式
RegularExpressionLiteral
: { areRegularExpressionsEnabled() }?=> DIV RegularExpressionFirstChar RegularExpressionChar* DIV IdentifierPart*
;