ANTLR:消除杂波
我现在正在学习ANTLR。比方说,我有一个VHDL代码,希望对进程块进行一些处理。其余的应该完全忽略。我不想描述整个VHDL语言,因为我只对进程块感兴趣。所以我可以编写一个匹配进程块的规则。但是我如何告诉ANTLR只匹配进程块规则而忽略任何其他内容呢?我几乎不知道VHDL,所以假设您想用多行注释替换Java源文件中的所有单行注释:ANTLR:消除杂波,antlr,antlr3,Antlr,Antlr3,我现在正在学习ANTLR。比方说,我有一个VHDL代码,希望对进程块进行一些处理。其余的应该完全忽略。我不想描述整个VHDL语言,因为我只对进程块感兴趣。所以我可以编写一个匹配进程块的规则。但是我如何告诉ANTLR只匹配进程块规则而忽略任何其他内容呢?我几乎不知道VHDL,所以假设您想用多行注释替换Java源文件中的所有单行注释: //foo 应成为: /* foo */ 当然,您需要让lexer匹配单行注释。但您还应确保它能够识别多行注释,因为您不希望//栏在以下情况下被识别为单行注释:
//foo
应成为:
/* foo */
当然,您需要让lexer匹配单行注释。但您还应确保它能够识别多行注释,因为您不希望//栏在以下情况下被识别为单行注释:
/*
//bar
*/
字符串文字也是如此:
String s = "no // comment";
最后,您应该在lexer中创建某种类型的catch-all规则,以匹配任何字符
快速演示:
grammar T;
parse
: (t=. {System.out.print($t.text);})* EOF
;
Str
: '"' ('\\' . | ~('\\' | '"'))* '"'
;
MLComment
: '/*' .* '*/'
;
SLComment
: '//' ~('\r' | '\n')*
{
setText("/* " + getText().substring(2) + " */");
}
;
Any
: . // fall through rule, matches any character
;
如果您现在像这样解析输入:
//comment 1
class Foo {
//comment 2
/*
* not // a comment
*/
String s = "not // a // comment"; //comment 3
}
以下内容将打印到您的控制台:
/* comment 1 */
class Foo {
/* comment 2 */
/*
* not // a comment
*/
String s = "not // a // comment"; /* comment 3 */
}
请注意,这只是一个快速演示:Java中的字符串文字可能包含Unicode转义,我的演示不支持这种转义,我的演示也不处理字符文字char literal char c='';我会打破它。当然,所有这些问题都很容易解决。我几乎不知道VHDL,所以假设您想用多行注释替换Java源文件中的所有单行注释:
//foo
应成为:
/* foo */
当然,您需要让lexer匹配单行注释。但您还应确保它能够识别多行注释,因为您不希望//栏在以下情况下被识别为单行注释:
/*
//bar
*/
字符串文字也是如此:
String s = "no // comment";
最后,您应该在lexer中创建某种类型的catch-all规则,以匹配任何字符
快速演示:
grammar T;
parse
: (t=. {System.out.print($t.text);})* EOF
;
Str
: '"' ('\\' . | ~('\\' | '"'))* '"'
;
MLComment
: '/*' .* '*/'
;
SLComment
: '//' ~('\r' | '\n')*
{
setText("/* " + getText().substring(2) + " */");
}
;
Any
: . // fall through rule, matches any character
;
如果您现在像这样解析输入:
//comment 1
class Foo {
//comment 2
/*
* not // a comment
*/
String s = "not // a // comment"; //comment 3
}
以下内容将打印到您的控制台:
/* comment 1 */
class Foo {
/* comment 2 */
/*
* not // a comment
*/
String s = "not // a // comment"; /* comment 3 */
}
请注意,这只是一个快速演示:Java中的字符串文字可能包含Unicode转义,我的演示不支持这种转义,我的演示也不处理字符文字char literal char c='';我会打破它。当然,所有这些问题都很容易解决。在即将推出的ANTLR v4中,您可以进行模糊解析。看看 您可以在此处获得测试版软件:
Terence在即将推出的ANTLR v4中,您可以进行模糊解析。看看 您可以在此处获得测试版软件:
特伦斯谢谢!ANTLR真是一部伟大的作品!你的书也很棒!非常感谢。ANTLR真是一部伟大的作品!你的书也很棒!谢谢你,巴特。我想知道是否有可能用符合任何规则的ANTLR数据捕获?比如说,我想捕获两个SLComment标记之间的所有文本,这怎么可能呢?谢谢@Bart。我想知道是否有可能用符合任何规则的ANTLR数据捕获?比如说,我想捕获两个SLComment标记之间的所有文本,怎么可能呢?