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

如何忽略ANTLR中大括号内的任意内容?

马阳晖
2023-03-14

我正在尝试编写一个配置文件语法并让ANTLR4来处理它。我对ANTLR很陌生(这是我第一个使用它的项目)。

在很大程度上,我理解大多数配置文件语法需要做什么(或者至少我认为我需要做什么),但我将要阅读的文件将在大括号内包含任意C代码。以下是一个示例:

类似于:

@DEVICE: servo "servos are great"
@ACTION: turnRight "turning right is fun"
{
arbitrary C source code goes here;
some more arbitrary C source code;
}
@ACTION: secondAction "this is another action"
{
some more code;
}

可能有很多这样的人。我似乎无法让它理解我只想忽略(不跳过)源代码。以下是我迄今为止的语法:

/**
ANTLR4 grammar for practicing
*/
grammar practice;


file:       (devconfig)*
    ;

devconfig:  devid (action)+
    ;

devid:      DEV_HDR (COMMENT)?
    ;

action:     ACTN_HDR '{' C_BLOCK '}'
    ;



DEV_HDR:    '@DEVICE: ' ALPHA+(IDCHAR)*
    ;

fragment
ALPHA:      [a-zA-Z]
    ;

fragment
IDCHAR:     ALPHA
    |       [0-9]
    |       '_'
    ;

COMMENT:    '"' .*? '"'
    ;

ACTN_HDR:   '@ACTION: ' ACTION_ID
    ;
fragment
ACTION_ID:  ALPHA+(IDCHAR)*
    ;

C_BLOCK:    WHAT DO I PUT HERE?? -> channel(HIDDEN)
    ;

WS:     [ \t\n\r]+ -> skip
    ;

问题是,我在C\U BLOCK lexer规则中输入的任何内容似乎都会把整个事情搞砸,就像我输入。*-

共有1个答案

萧波峻
2023-03-14

您的C_BLOCK规则可以像通常的多行注释规则一样在许多语言中进行定义。也将花括号作为规则的一部分:

C_BLOCK: CURLY .*? CURLY -> channel(HIDDEN);

如果需要嵌套块,请编写如下内容:

C_BLOCK: CURLY .*? C_BLOCK? .*? CURLY -> channel(HIDDEN);

或者可能:

C_BLOCK:
    CURLY (
      C_BLOCK
      | .
    )*?
    CURLY
;

(未测试)。

更新:根据评论的建议,更改了代码以使用非贪婪的kleene运算符。

 类似资料:
  • 问题内容: 因此,作为我的应用程序的一部分,我需要它从文本文件中读取数据,并在大括号之间获取元素。 例如: 服务器_1 { / directory1 / directory2 } 服务器_2 { /目录1 /目录2 } 然后类似if ,打印目录。 亲切的问候, 问题答案: 您可以尝试以下操作: 说明 匹配任何字符 量词-匹配零到无限次,次数尽可能少,根据需要扩展(延迟) 从字面上匹配字符(区分大小

  • 问题内容: 我已经看到了许多相关的问题,但是都没有直接解决我想做的事情。我正在从CSV文件中读取文本行。 所有项目都用引号引起来,有些则在引号内有其他逗号。我想按逗号分隔行,但忽略引号内的逗号。有没有一种方法可以在Python中执行此操作,而无需使用许多正则表达式语句。 一个例子是: 我想将其解析为4个单独的值变量: 我想念一个简单的选择吗? 问题答案: 不要尝试重新发明轮子。 如果要读取CSV文

  • 以下是降价文本的示例: #“我的标题” !图像标题。{ 样式=“浮动:右; 宽度: 20%; 边框: 1px”} 有的“引用文字”,有的*“强调文字”*等。 在bash脚本中,我试图用法语引号替换任何双引号。 例如:“word”应变成« 换句话说,一个单词前的所有引号都应该替换为一个开放的法语引号,后跟一个不间断的空格;而且一个单词后面的所有引号都要换成一个不换行的空格后面跟着一个闭合的法语引号;

  • 我想将“word1和word2或(word3和(word4或word5))和word6”等字符串与“和”分开,以便从括号外获得:“word1”“word2或(word3和(word4或word5))”“word6” 请注意,括号组可以包含许多其他括号组。 我做了一些研究,我发现了一个正则表达式,它与我想要的相反:这个正则表达式选择括号之外的“AND”以外的所有内容。我还尝试了前瞻和后视,但没有成功

  • 这是我前面的SO问题的一个排列。这个答案对我来说非常有效,直到我遇到了一个导致问题的边缘案例。我现在需要一个调整的正则表达式模式。我试着在Regex Storm上自己解决这个问题,但是我对Regex的了解还不够深入。 与我上一篇文章(链接在上面)的一个变化是,我现在只对匹配以开头的paren分组感兴趣,而不是仅仅以开头。分组的结尾保持不变: 我正在使用C#和regex,试图捕获外部的paren组,

  • 我正在开发代表Surf WebScript的内容上传器。也许说updater更正确,因为内容已经存在于存储库中,但可能没有方面。我需要更新此内容并设置正确的版本号(例如,任意)。 我注意到第一次上传总是得到数字。 例如,假设内容模型没有特性。我可以通过这种方式添加它,并指定我需要的版本号(): 我使用的常量: 当我调试这个解决方案时,我可以看到我得到了我需要的版本。 然而,当我在节点浏览器中查看节