antlr 重写规则的输出
我正在尝试编写一个antlr脚本,其中rule1有一个子规则rule2。我在规则 1 上使用 StringTemplate。
我想要做的是在规则 1 消耗/使用规则 2 匹配的文本之前重构它。我该怎么做?
options{
output=template;
}
rule1 :
begin sub-rule2 end ';' -> meth(body={rule1.text})
sub-rule2 :
sub-rule3
| sub-rule4
| sub-rule5;
这里“meth”是字符串模板调用
如果说子规则4匹配“select * from Dual;”,我希望将其传递给规则1“#sql (select * from Dual);”。
这是我的实际代码,我希望将 select_statement 规则匹配的语句包装在“#sql()”中,并在“stats”列表中传递到“meth”模板的“body”属性:
body
@init {
List stats = new ArrayList();
} :
BEGIN s=statement{ stats.add($s.text); } SEMI ( s=statement{ stats.add($s.text); } SEMI | pragma SEMI )*
( EXCEPTION exception_handler+ )? END ID? -> method(modifiers={"public"},returnType={"void"},name={"execute"},body={stats})
;
statement :
label*
( assign_or_call_statement
| case_statement
| close_statement
| continue_statement
| basic_loop_statement
| execute_immediate_statement
| exit_statement
| fetch_statement
| for_loop_statement
| forall_statement
| goto_statement
| if_statement
| null_statement
| open_statement
| plsql_block
| raise_statement
| return_statement
| sql_statement
| while_loop_statement
)
;
sql_statement
: (commit_statement
| delete_statement
| insert_statement
| lock_table_statement
| rollback_statement
| savepoint_statement
| select_statement
| set_transaction_statement
| update_statement )
;
select_statement :
SELECT swallow_to_semi
;
SELECT : 'select';
swallow_to_semi :
~( SEMI )+
;
I am trying to write an antlr script where in, rule1 has a subrule , rule2. I am using StringTemplate on rule 1.
What I want to do, is restructure the text matched by rule2 before it is consumed/used by rule1. How do I do that ?
options{
output=template;
}
rule1 :
begin sub-rule2 end ';' -> meth(body={rule1.text})
sub-rule2 :
sub-rule3
| sub-rule4
| sub-rule5;
here "meth" is the stringtemplate call
If say sub-rule 4 matches "select * from dual;", I would like this to be passed to rule1 "#sql (select * from dual);".
Here is my Actual code I would like the statements matched by the select_statement rule to be wrapped in '#sql()' and to be passed in "stats" list to the "body" attribute of the "meth" template :
body
@init {
List stats = new ArrayList();
} :
BEGIN s=statement{ stats.add($s.text); } SEMI ( s=statement{ stats.add($s.text); } SEMI | pragma SEMI )*
( EXCEPTION exception_handler+ )? END ID? -> method(modifiers={"public"},returnType={"void"},name={"execute"},body={stats})
;
statement :
label*
( assign_or_call_statement
| case_statement
| close_statement
| continue_statement
| basic_loop_statement
| execute_immediate_statement
| exit_statement
| fetch_statement
| for_loop_statement
| forall_statement
| goto_statement
| if_statement
| null_statement
| open_statement
| plsql_block
| raise_statement
| return_statement
| sql_statement
| while_loop_statement
)
;
sql_statement
: (commit_statement
| delete_statement
| insert_statement
| lock_table_statement
| rollback_statement
| savepoint_statement
| select_statement
| set_transaction_statement
| update_statement )
;
select_statement :
SELECT swallow_to_semi
;
SELECT : 'select';
swallow_to_semi :
~( SEMI )+
;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以像这样具体定义规则可以返回什么:
现在
sub_rule2
返回一个String x
,您可以像这样使用它:注意
sub_rule2.x
>。编辑
您还可以创建一个自定义方法来检查要添加到
List
的文本是否以"select "
开头,如下所示:You can specifically define what a rule can return like this:
Now
sub_rule2
returns aString x
which you can use like this:Note the
sub_rule2.x
.EDIT
You could also create a custom method that checks if the text to be added to the
List
starts with"select "
like this: