Antlr 如何更改表达式以强制调用生成的解析器中的RewriteRuleSubtreeStream.NextTree()?
我是一个ANTLR新手,正在尝试将早期的ANTLR 3.1语法更新为3.4。我遇到的一个绊脚石是我生成的解析器。有一行代码调用NextNode(),我希望它调用NextTree(),这样我的解析器就会执行所需的行为 我所讨论的ANTLR表达式是:Antlr 如何更改表达式以强制调用生成的解析器中的RewriteRuleSubtreeStream.NextTree()?,antlr,antlr3,Antlr,Antlr3,我是一个ANTLR新手,正在尝试将早期的ANTLR 3.1语法更新为3.4。我遇到的一个绊脚石是我生成的解析器。有一行代码调用NextNode(),我希望它调用NextTree(),这样我的解析器就会执行所需的行为 我所讨论的ANTLR表达式是: cast : ('(' ssisType (',' INT)* ')') term -> ^(CAST ^( ssisType INT*) term) ; SSIS类型定义为: ssisType : ( typeCode =
cast : ('(' ssisType (',' INT)* ')') term -> ^(CAST ^( ssisType INT*) term)
;
SSIS类型定义为:
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添加的子节点
我有没有办法改变表达来产生我想要的行为?我已尝试在表达式中的几个点插入^,但要么生成错误的结果,要么无法生成语法
非常感谢
-Craig你不能这么做:你直接放在
^(
(根)后面的东西总是被认为是一个节点,没有树
稍微不同的方式:
cast
: ('(' ssisType (',' INT)* ')') term -> ^(CAST ^(SSISTYPE ssisType INT*) term)
;
ssisType
: 'DT_I1'
| 'DT_I2'
// ...
;
这将解析输入:
(DT_I2, 42, 666)123456
进入以下步骤:
您不能这样做:您直接放置在
^(
(根)后面的内容将始终被视为单个节点,而不是树
稍微不同的方式:
cast
: ('(' ssisType (',' INT)* ')') term -> ^(CAST ^(SSISTYPE ssisType INT*) term)
;
ssisType
: 'DT_I1'
| 'DT_I2'
// ...
;
这将解析输入:
(DT_I2, 42, 666)123456
进入以下步骤: