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

ANTLR4将任何不匹配的节匹配到一个字符串标记中

唐康安
2023-03-14

我试图用ANTLR创建一个lexer/parser,它可以解析中间分散有标记的纯文本。这些标记由打开({)和关闭(})括号表示,它们表示可以计算为字符串的Java对象,然后在原始输入中替换该字符串,以创建排序的动态模板。

这里有一个例子:{player:name}向你问好!{player:name}应该被玩家的名字替换,并导致输出,即Mark say hi!为了那个叫马克的玩家。

现在我可以很好地识别和解析标记,但我遇到的问题是后面的文本。这是我使用的语法:

    grammar : content+

    content : tag 
            | literal
            ;

    tag : player_tag
        | <...>
        | <other kinds of tags, not important for this example>
        | <...>
        ;

    player_tag : BRACKET_OPEN player_identifier SEMICOLON player_string_parameter BRACKET_CLOSE ;
    player_string_parameter : NAME
                            | <...>
                            ;
    player_identifier : PLAYER ;

    literal : NUMBER
            | STRING
            ;

    BRACKET_OPEN : '{';
    BRACKET_CLOSE : '}';

    PLAYER : 'player'
    NAME : 'name'

    NUMBER : <...>
    STRING : (.+)? /* <- THIS IS THE PROBLEMATIC PART !*/
  STRING : '\'' ~[}{]+ '\'' ;
  STRING : (?<=})(.+)?(?={) ;

对该做什么有什么建议吗?

共有1个答案

邓光赫
2023-03-14

Antlr不支持lookahead或LookBehind。它确实支持非贪婪通配符匹配,但仅当.*非贪婪通配符在规则中跟随终止序列时(正如您所说,终止序列也包含在匹配中,尽管您可以将其推回到输入流中)。

所以~[{}]*是正确的。但是有一个小问题:lexer规则(通常)总是活动的。因此,lexer规则在大括号内也是活动的,这意味着它将吞下大括号之间的全部内容(除非有嵌套大括号或引号内的大括号,否则情况更糟)。

因此,您需要定义不同的词汇内容,在ANTLR中称为“词汇模式”。在Antlr权威参考中有一个公开可见的示例,它展示了一个非常类似的问题的解决方案:解析HTML。

 类似资料:
  • null 显然,我可以尝试在lexer语法中以以下方式解决这个问题: 但它也将包含结束标记,解析器语法更难看。 (加分题: 如何在中正确捕获空格,但可能需要使用lexer模式; 如何避免和其他lexer定义的干扰。)

  • 问题 你想要匹配两个或多个字符串。 解决方案 计算把一个字符串转换成另一个字符串所需的编辑距离或操作数。 levenshtein = (str1, str2) -> l1 = str1.length l2 = str2.length prevDist = [0..l2] nextDist = [0..l2] for i in [1..l1] by 1

  • 我是ANTLR的新手。我想写一个语法来解析下面的输入: 语法如下:: 当我尝试使用语法解析上述输入时,它会引发以下异常:: 第1行:0不匹配的输入'commit a1b2c3d4',应为'commit' 我已经引用了ANTLR4:不匹配的输入链接,但仍然不清楚发生了什么。

  • 问题内容: 假设我在SQL中有数百万行,使用PostgreSQL进行查询。每行是否包含字符串。在所有行中,我需要获取包含CONTAINS的行。 那么最好的查询方式是什么? 我尝试了以下操作,但是速度非常慢。 我应该使用什么? 问题答案: 您需要找出一种方法来建立索引或使用其他类似搜索引擎的方法。 首先看一下为什么LIKE在postgresl中会变慢,以及如何使我在use-the-index-luk

  • 我试图检查字符串是否包含完全匹配。例如: String str="这是我的字符串,具有-Policy和-p" 我怎样才能做到以下几点: