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

时间:2015-03-02 22:57:32

标签: antlr antlr4

我正在尝试编写配置文件语法并获取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_BLOCK词法分析器规则中放置什么似乎搞砸了整个事情 - 就像我放了。*? - >通道(HIDDEN),它似乎根本不起作用(当然,在语法上使用ANTLR时出现错误“。*?可以匹配空字符串” - 但如果在那里我应该放在哪里不是这样,所以它忽略了C代码,但是以后我可以访问它(即不跳过它)?

1 个答案:

答案 0 :(得分:0)

您的C_BLOCK规则可以像通常的多行注释规则一样在很多语言中完成。使花括号成为规则的一部分:

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

如果您需要嵌套块,请编写类似:

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

或者也许:

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

(未测试的)。

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