JavaScript ECMA 脚本派生语法错误

JavaScript ECMA script derived grammar error

我正在创建一个从 ECMA 脚本语法派生的简化语法:

https://github.com/antlr/grammars-v4/blob/master/ecmascript/ECMAScript.g4

到目前为止,原始语法工作正常,我只添加了一些规则。但是,以下表达式在我的语法中是有效的表达式,但在原始 ECMA 语法中会引发错误:

round(frames++/((getTime()-start)/1000))

引起

frames++/

表达式。

而以下类似表达式有效:

round(frames++*((getTime()-start)/1000))
round(frames++%((getTime()-start)/1000))

我的问题是如何使第一个表达式起作用,有什么区别?

这可能是因为 / 被解释为正则表达式定界符的开始。

如果您查看确定 / 何时为正则表达式文字以及何时为除法运算符的词法分析器方法:

/**
 * Returns {@code true} iff the lexer can match a regex literal.
 *
 * @return {@code true} iff the lexer can match a regex literal.
 */
private boolean isRegexPossible() {

    if (this.lastToken == null) {
        // No token has been produced yet: at the start of the input,
        // no division is possible, so a regex literal _is_ possible.
        return true;
    }

    switch (this.lastToken.getType()) {
        case Identifier:
        case NullLiteral:
        case BooleanLiteral:
        case This:
        case CloseBracket:
        case CloseParen:
        case OctalIntegerLiteral:
        case DecimalLiteral:
        case HexIntegerLiteral:
        case StringLiteral:
            // After any of the tokens above, no regex literal can follow.
            return false;
        default:
            // In all other cases, a regex literal _is_ possible.
            return true;
    }
}

那么对于标记 --++.

,这也应该 return 为假

调整isRegexPossible()如下:

private boolean isRegexPossible() {

    if (this.lastToken == null) {
        // No token has been produced yet: at the start of the input,
        // no division is possible, so a regex literal _is_ possible.
        return true;
    }

    switch (this.lastToken.getType()) {
        case Identifier:
        case NullLiteral:
        case BooleanLiteral:
        case This:
        case CloseBracket:
        case CloseParen:
        case OctalIntegerLiteral:
        case DecimalLiteral:
        case HexIntegerLiteral:
        case StringLiteral:
        case PlusPlus:               // <-- NEW
        case MinusMinus:             // <-- NEW
            // After any of the tokens above, no regex literal can follow.
            return false;
        default:
            // In all other cases, a regex literal _is_ possible.
            return true;
    }
}