如何更改表达式以强制在生成的解析器中调用 RewriteRuleSubtreeStream.NextTree() ?
我是一名 ANTLR 新手,正在尝试将早期的 ANTLR 3.1 语法更新到 3.4。我遇到的一个绊脚石是我生成的解析器。有一行代码调用 NextNode(),我希望它改为调用 NextTree(),以便我的解析器执行所需的行为。
我的 ANTLR 表达式有问题是:
cast : ('(' ssisType (',' INT)* ')') term -> ^(CAST ^( ssisType INT*) term)
;
ssisType 定义为:
ssisType
:
( typeCode ='DT_I1'
| typeCode ='DT_I2'
| typeCode ='DT_I4'
| typeCode ='DT_I8'
| typeCode ='DT_R4'
| typeCode ='DT_R8'
| typeCode ='DT_CY'
| typeCode ='DT_DATE'
| typeCode ='DT_BOOL'
| typeCode ='DT_NUMERIC'
| typeCode ='DT_DECIMAL'
| typeCode ='DT_UI1'
| typeCode ='DT_UI2'
| typeCode ='DT_UI4'
| typeCode ='DT_UI8'
| typeCode ='DT_GUID'
| typeCode ='DT_BYTES'
| typeCode ='DT_STR'
| typeCode ='DT_WSTR'
| typeCode ='DT_DBDATE'
| typeCode ='DT_DBTIME'
| typeCode ='DT_DBTIME2'
| typeCode ='DT_DBTIMESTAMP'
| typeCode ='DT_DBTIMESTAMP2'
| typeCode ='DT_DBTIMESTAMPOFFSET'
| typeCode ='DT_FILETIME'
| typeCode ='DT_IMAGE'
| typeCode ='DT_TEXT'
| typeCode ='DT_NTEXT') -> ^(SSISTYPE $typeCode)
在我的解析器(在 C# 中)中,处理表达式右侧的代码的生成部分是:
retval.Tree = root_0;
RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null);
root_0 = (CommonTree)adaptor.Nil();
// 99:44: -> ^( CAST ^( ssisType ( INT )* ) term )
{
DebugLocation(99, 47);
// SsisGrammar.g:99:47: ^( CAST ^( ssisType ( INT )* ) term )
{
CommonTree root_1 = (CommonTree)adaptor.Nil();
DebugLocation(99, 49);
root_1 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(CAST, "CAST"), root_1);
DebugLocation(99, 54);
// SsisGrammar.g:99:54: ^( ssisType ( INT )* )
{
CommonTree root_2 = (CommonTree)adaptor.Nil();
DebugLocation(99, 57);
root_2 = (CommonTree)adaptor.BecomeRoot(stream_ssisType.NextNode(), root_2);
DebugLocation(99, 66);
// SsisGrammar.g:99:66: ( INT )*
while ( stream_INT.HasNext )
{
DebugLocation(99, 66);
adaptor.AddChild(root_2, stream_INT.NextNode());
}
stream_INT.Reset();
adaptor.AddChild(root_1, root_2);
}
DebugLocation(99, 72);
adaptor.AddChild(root_1, stream_term.NextTree());
adaptor.AddChild(root_0, root_1);
}
}
我正在寻找一种方法来更改我的表达式,使其
root_2 = (CommonTree)adaptor.BecomeRoot(stream_ssisType.NextNode(), root_2);
变为
root_2 = (CommonTree)adaptor.BecomeRoot(stream_ssisType.NextTree(), root_2);
原因是树的顶部节点包含未使用 NextNode 添加的子节点。
有什么方法可以改变表达以产生我想要的行为吗?我尝试在表达式中的多个位置插入 ^,但要么生成错误的结果,要么无法构建语法。
非常感谢,
-克雷格
I'm an ANTLR novice that's trying to update an early ANTLR 3.1 grammar to 3.4. The one stumbling block I'm hitting is with my generated parser. There's a line of code that calls NextNode(), and I want it to call NextTree() instead, so my parser performs the desired behavior.
My ANTLR expression in question is:
cast : ('(' ssisType (',' INT)* ')') term -> ^(CAST ^( ssisType INT*) term)
;
ssisType is defined as:
ssisType
:
( typeCode ='DT_I1'
| typeCode ='DT_I2'
| typeCode ='DT_I4'
| typeCode ='DT_I8'
| typeCode ='DT_R4'
| typeCode ='DT_R8'
| typeCode ='DT_CY'
| typeCode ='DT_DATE'
| typeCode ='DT_BOOL'
| typeCode ='DT_NUMERIC'
| typeCode ='DT_DECIMAL'
| typeCode ='DT_UI1'
| typeCode ='DT_UI2'
| typeCode ='DT_UI4'
| typeCode ='DT_UI8'
| typeCode ='DT_GUID'
| typeCode ='DT_BYTES'
| typeCode ='DT_STR'
| typeCode ='DT_WSTR'
| typeCode ='DT_DBDATE'
| typeCode ='DT_DBTIME'
| typeCode ='DT_DBTIME2'
| typeCode ='DT_DBTIMESTAMP'
| typeCode ='DT_DBTIMESTAMP2'
| typeCode ='DT_DBTIMESTAMPOFFSET'
| typeCode ='DT_FILETIME'
| typeCode ='DT_IMAGE'
| typeCode ='DT_TEXT'
| typeCode ='DT_NTEXT') -> ^(SSISTYPE $typeCode)
In my parser (in C#), the generated portion of code that processes the right hand side of the expression is:
retval.Tree = root_0;
RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null);
root_0 = (CommonTree)adaptor.Nil();
// 99:44: -> ^( CAST ^( ssisType ( INT )* ) term )
{
DebugLocation(99, 47);
// SsisGrammar.g:99:47: ^( CAST ^( ssisType ( INT )* ) term )
{
CommonTree root_1 = (CommonTree)adaptor.Nil();
DebugLocation(99, 49);
root_1 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(CAST, "CAST"), root_1);
DebugLocation(99, 54);
// SsisGrammar.g:99:54: ^( ssisType ( INT )* )
{
CommonTree root_2 = (CommonTree)adaptor.Nil();
DebugLocation(99, 57);
root_2 = (CommonTree)adaptor.BecomeRoot(stream_ssisType.NextNode(), root_2);
DebugLocation(99, 66);
// SsisGrammar.g:99:66: ( INT )*
while ( stream_INT.HasNext )
{
DebugLocation(99, 66);
adaptor.AddChild(root_2, stream_INT.NextNode());
}
stream_INT.Reset();
adaptor.AddChild(root_1, root_2);
}
DebugLocation(99, 72);
adaptor.AddChild(root_1, stream_term.NextTree());
adaptor.AddChild(root_0, root_1);
}
}
I'm looking for a way to change my expression so that
root_2 = (CommonTree)adaptor.BecomeRoot(stream_ssisType.NextNode(), root_2);
becomes
root_2 = (CommonTree)adaptor.BecomeRoot(stream_ssisType.NextTree(), root_2);
The reason is that the Tree's top node contains Children that aren't being added using NextNode.
Is there I way I can change the expression to produce my desired behavior? I've tried inserting an ^ at several spots within the expression but either the wrong result is generated or the grammar won't build.
Thanks very much,
-Craig
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你不能这样做,据我所知:你直接放在
^(
(根)之后的内容将始终被视为单个节点,而不是树。不同的方式:
它将解析输入:
稍微 以下 AST:
You can't do that AFAIK: what you place directly after the
^(
(the root) will always be considered a single node, no tree.An slightly different way:
which will parse the input:
into the following AST: