当前位置: 首页 > 知识库问答 >
问题:

确保表达式不以字符结尾的ANTLR4 lexer规则

卜鹏
2023-03-14
some-Text->more-Text

从这个例子中,我需要将'some-text'和'more-text'匹配到一个lexer规则中的ANTLR4 lexer规则,并将'->'作为另一个规则。

我使用下面显示的lexer规则作为我的起点,但问题是NAMEDELEMENT规则中允许使用'-'字符,这会导致第一个NAMEDELEMENT匹配变成'some-text-',然后导致边缘规则无法捕获'->'。

我正在寻找一种方法来确保'-'不被捕获为NAMEDELEMENT规则中的最后一个字符(或其他产生所需结果的替代方案)。

EDGE
    :   '->'
    ;

NAMEDELEMENT  
    :   ('a'..'z'|'A'..'Z'|'_'|'@') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')* { _input.LA(1) != '-' && _input.LA(2) != '>' }?
    ;

解析器规则如下所示,其中我匹配“选择器”规则:

selector
    :   namedelement (edge namedelement)*
    ;

edge
    :   EDGE
    ;

namedelement
    :   NAMEDELEMENT
    ;

提前道谢!

共有1个答案

羊舌承天
2023-03-14

经过几个小时的折腾,我有了一个有效的语法,尽管我看不出它在功能上与我在原问题中发布的有什么不同。

(我使用未注释的版本,这样我就可以在生成的lexer中放置一个断点,以确保相等性测试的评估正确。)

NAMEDELEMENT  
    //: [a-zA-Z_@] [a-zA-Z_-]* { String.fromCharCode(this._input.LA(1)) != ">" }? 
    : [a-zA-Z_@] [a-zA-Z_-]* { (function(a){
            var c = String.fromCharCode(a._input.LA(1));
            return c != ">";
        })(this)
    }? 
    ;

我的目标语言是JavaScript,谓词的注释形式和未注释形式都可以正常工作。

 类似资料:
  • 虽然它的缺点是,它不匹配一个字符的字符串。

  • 问题内容: 我想测试一个字符串是否以a结束。我希望下面的Java行能打印出正确的文字。为什么打印错误? 问题答案: 在Java Regex中,(在String中的任意位置找到匹配项)和(与整个String匹配)之间存在区别。 String仅具有一个方法(实现等效于以下代码:),因此您需要创建一个与完整String匹配的模式:

  • 问题内容: 给定以下内容: 我想捕捉: 什么Java正则表达式可以让我做到这一点? 我已经尝试过了,它对于“约翰·史密斯(123)”和“约翰·史密斯(123)(456)”都适用,但是对“约翰·史密斯”却不起作用。如何更改正则表达式以使其也可用于第一个输入? 问题答案: 您可以将第一个懒惰的人变成懒惰的人,然后用一个非捕获的可选组来包裹后面的部分: 参见正则表达式演示 实际上,如果将正则表达式与最后

  • 如果我有一个= 我使用indexof方法删除所有字符,那么字符串的最终输出应该是 我已经编写了但这只会从_的第一个索引中删除字符,它将得到curr_29jan2021_061420210106999.txt,有没有任何方法可以从最后两个而不是第一个中删除字符

  • 我想在Java中使用Regex提取某种字符串。我目前有这样的模式: 应该匹配以“a”开头、以“se”结尾的字符串。这不起作用。我错过了什么吗? 删除了模式末尾的 \n 行并将其替换为“$”:仍然没有匹配项。正则表达式从我这边看起来是合法的。 我想提取的是从临时字符串中提取的“a se”。

  • 问题内容: 我需要一个不以点开头或不以开头的正则表达式。 此正则表达式有效,但在第一个条件下失败;它不以点开头: 例如:应为有效字符串,但失败。 问题答案: 从上一个问题开始,您应该可以使用: 但是,如果您希望能够匹配1个字符串,则需要否定先行: 而且,如果您也想匹配空字符串,只需使用代替即可。