我如何忽略 ANTLR 中大括号内的任意内容?
How do I ignore arbitrary stuff inside braces in ANTLR?
我正在尝试编写一个配置文件语法并让 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 词法分析器规则中输入什么,似乎都会搞砸整个事情——就像我输入 .*? -> channel(HIDDEN),它似乎根本不起作用(当然,在语法上使用 ANTLR 时出现错误“.*?可以匹配空字符串” - 但我应该放什么如果不是那样的话,它会忽略 C 代码,但是我以后可以访问它(即不跳过它)?
您的 C_BLOCK 规则可以像通常的多行注释规则一样在多种语言中定义。也使花括号成为规则的一部分:
C_BLOCK: CURLY .*? CURLY -> channel(HIDDEN);
如果你需要嵌套块,你可以这样写:
C_BLOCK: CURLY .*? C_BLOCK? .*? CURLY -> channel(HIDDEN);
或者也许:
C_BLOCK:
CURLY (
C_BLOCK
| .
)*?
CURLY
;
(未测试)。
更新:更改代码以使用评论建议的非贪婪 kleene 运算符。
我正在尝试编写一个配置文件语法并让 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 词法分析器规则中输入什么,似乎都会搞砸整个事情——就像我输入 .*? -> channel(HIDDEN),它似乎根本不起作用(当然,在语法上使用 ANTLR 时出现错误“.*?可以匹配空字符串” - 但我应该放什么如果不是那样的话,它会忽略 C 代码,但是我以后可以访问它(即不跳过它)?
您的 C_BLOCK 规则可以像通常的多行注释规则一样在多种语言中定义。也使花括号成为规则的一部分:
C_BLOCK: CURLY .*? CURLY -> channel(HIDDEN);
如果你需要嵌套块,你可以这样写:
C_BLOCK: CURLY .*? C_BLOCK? .*? CURLY -> channel(HIDDEN);
或者也许:
C_BLOCK:
CURLY (
C_BLOCK
| .
)*?
CURLY
;
(未测试)。
更新:更改代码以使用评论建议的非贪婪 kleene 运算符。