jsx中antlr4解析templateLiteral

Antlr4 parsing templateLiteral in jsx

我尝试使用grammars-v4项目(https://github.com/antlr/grammars-v4/tree/master/javascript/jsx)中定义的语法来解析jsx文件。 当我解析下面的代码片段时,

let str =
        `${dsName}${parameterStr ? `( ${parameterStr} )` : ""}${returns ? `{
${returns}}` : ""}`;

显示如下错误

 line 2:32 at [@8,42:42='(',<8>,2:32]:no viable alternative at input '('

https://astexplorer.net/ 显示它是一个 TemplateLiteral,里面有 conditionalExpression,对解析这种语法有什么想法吗?

提前致谢。

编辑: 谢谢@Bart,它有效。

在下面的代码中运行良好。

const href1 = `https://example.com/lib/downloads_${page}.htm?joinSource=${joinSource}${inviter?`&inviter=${inviter}`: ''}`;

const href2 = `https://example.com/act/kol/detail_${this.props.values.list.res.rows && this.props.values.list.res.rows[0].id}_${page}.htm?joinSource=${joinSource}${inviter?`&inviter=${inviter}`: ''}`;

快速浏览一下 ANTLR 语法表明:

// TODO: `${`tmp`}`
TemplateStringLiteral:          '`' ('\`' | ~'`')* '`'

所以,显然,它在“TODO 列表”上。允许嵌套的“`”字符串插值是令人惊讶的(至少可以说),并且对于 ANTLR Lexer 来说将是“非常重要的”(所以,我不会“屏住呼吸”等待修复)。

您尝试过吗:(将嵌套的“`”替换为“'s?)。

let str =
        `${dsName}${parameterStr ? “( ${parameterStr} )” : ""}${returns ? “{
${returns}}” : ""}`;

根据 Mike 的观察,是模板字符串造成了混乱,这里有一个快速解决方案:

变化:

JavaScriptLexerBase.java

添加实例变量:

// Keeps track of the the current depth of nested template string backticks. 
// E.g. after the X in:
// 
// `${a ? `${X
//
// templateDepth will be 2. This variable is needed to determine if a `}` is a 
// plain CloseBrace, or one that closes an expression inside a template string. 
protected int templateDepth = 0;

JavaScriptLexer.g4

// Place TemplateCloseBrace above CloseBrace!
TemplateCloseBrace: {this.templateDepth > 0}? '}' -> popMode;

...

// Remove (or comment) TemplateStringLiteral
// TemplateStringLiteral:          '`' ('\`' | ~'`')* '`';

BackTick
    : '`' {this.templateDepth++;} -> pushMode(TEMPLATE)
    ;

...

// Place at the end of the file:
mode TEMPLATE;

BackTickInside
    : '`' {this.templateDepth--;} -> type(BackTick), popMode
    ;

TemplateStringStartExpression
    : '${' -> pushMode(DEFAULT_MODE)
    ;

TemplateStringAtom
    : ~[`]
    ;

JavaScriptParser.g4

singleExpression
    : ...
    | singleExpression templateStringLiteral    # TemplateStringExpression  // ECMAScript 6
    | ...
    ;

literal
    : ...
    | templateStringLiteral
    | ...
    ;

templateStringLiteral
    : BackTick templateStringAtom* BackTick
    ;

templateStringAtom
    : TemplateStringAtom
    | TemplateStringStartExpression singleExpression TemplateCloseBrace
    ;

我没有完全测试我的解决方案,但它成功解析了您的示例输入: