【问题】
想要用antlr去实现匹配C语言代码。
其中有
{ xxx { xxx } xxx }
之类的大括号的递归。
需要用antlr写对应的语法,去匹配此递归。
【解决过程】
1。关于递归,供参考的一些资料:
官网的:
Left-Recursion Removal – Print Edition
别人写的:
ANTLR analysis of recursive structures
2.貌似别人也可以正常实现递归的:
How to remove Left recursive in this ANTLR grammer?
3.经过折腾,暂时还未解决。
目前的语法是:
method_definition : 'DEFINITION' '{' eddl_c_code '}'; eddl_c_code : ( any_char | bracket_body)*; any_char: (options {greedy=true;} : (~('{' | '}'))+); bracket_body : '{' (bracket_body | any_char? ) '}';
4.参考:
ANTLR: how to parse a region within matching brackets with a lexer
去写了些代码:
eddl_c_code // : ( any_char | bracket_body)*; : ( any_char | bracket_body)*; //any_char: (options {greedy=true;} : (~('{' | '}'))); any_char: (~('{' | '}'))+; //bracket_body // : '{'{depth++;} (any_char* | bracket_body ) '}'; bracket_body @init{int depth = 1;} : '{' ( {depth > 0}?=> // keep reapeating `{ ... }*` as long as depth > 0 ( ~('{' | '}') // match anything other than bracket | '{' {depth++;} // match a '{' in increase the var `open` | '}' {depth--;} // match a '}' in decrease the var `open` ) )*;
但是结果编译debug代码时出错了。
结果发现parser中,没有对应的depth变量的定义,所以才出错的。
但是把bracket_body改为BRACKET_BODY,结果却又编译不通过。
有空继续参考该贴,去折腾,貌似可以去匹配嵌套的情况的。
5.后来的后来,无意间的折腾,使用:
eddl_c_code : ( any_char | bracket_body)+; //any_char: (options {greedy=true;} : (~('{' | '}'))); any_char: (~('{' | '}'))+; bracket_body // : '{'{depth++;} (any_char* | bracket_body ) '}'; : '{' (any_char | bracket_body )+ '}';
竟然是可以正常识别那一堆的才代码了。
竟然没有再报错。
其中可见,使用加号’+’而不是星号’*’,会有个问题,那就是对于大括号内为空的情况,则是不允许的。
6.修改了一处的加号,变为星号,也是可以工作的:
eddl_c_code : ( any_char | bracket_body)+; //any_char: (options {greedy=true;} : (~('{' | '}'))); any_char: (~('{' | '}'))+; bracket_body // : '{'{depth++;} (any_char* | bracket_body ) '}'; // : '{' (any_char | bracket_body )+ '}'; : '{' (any_char | bracket_body )* '}';
7.最后改为:
method_definition : 'DEFINITION' '{' eddl_c_code '}'; eddl_c_code // : ( any_char | bracket_body)+; : ( any_char | bracket_body)*; //any_char: (options {greedy=true;} : (~('{' | '}'))); any_char: (~('{' | '}'))+; bracket_body // : '{'{depth++;} (any_char* | bracket_body ) '}'; // : '{' (any_char | bracket_body )+ '}'; : '{' (any_char | bracket_body )* '}';
也是可以正常工作的。
【总结】
好不容易,至少先让antlr的递归的语法,可以正常运行了。
注:
此处,还是会有些缺点,比如eddl_c_code和any_char会有多重匹配的问题,所以会有警告:
对应的提示为:
但是,至少暂时可以匹配到所有的C代码了。
转载请注明:在路上 » 【基本解决】用antlr匹配嵌套递归的代码