为什么输入.TokenStream解析为空
本文关键字:输入 TokenStream 为什么 | 更新日期: 2023-09-27 18:01:25
用鹿角,我正试图为一棵树做一个TreeWalker:
输入:int x = 3
输出AST: ^(VARDEF int x 3)
我的解析器工作得很好,还生成了一个AST,如上面所示,但是每当我想从AST中解析任何东西时,比如使用$variableType。在生成的c# 2.0 TreeWalker中,总是有一个NullReferenceException。
我通过treewalk:tree grammar SGLTreeWalker;
options {
tokenVocab = SGL;
language = 'CSharp2';
}
[...]
compilationUnit
: (statement)+
;
statement
: variableDefinitionList
;
variableDefinitionList
: ^(VARDEF variableType variableName expression) { Console.WriteLine($variableType.text); }
;
[...]
规则"variableDefinitionList"生成的有问题的部分如下所示:
Match(input, Token.UP, null);
Console.WriteLine(((variableType1 != null) ? input.TokenStream.ToString(
input.TreeAdaptor.GetTokenStartIndex(variableType1.Start),
input.TreeAdaptor.GetTokenStopIndex(variableType1.Start)) : null));
结果是输入。TokenStream是空的,所以它会抛出NullReferenceException。我读到,如果使用的TreeNodeStream没有缓冲,这可能会发生,但我使用了CommonTreeNodeStream,所以我认为它应该被缓冲。下面是我用来提交AST的代码:
[...]
SGLParser parser = new SGLParser(tStream);
CommonTree t = (CommonTree) parser.compilationUnit().Tree;
Console.WriteLine("; " + t.ToStringTree());
CommonTreeNodeStream treeStream = new CommonTreeNodeStream(t);
SGLTreeWalker tw = new SGLTreeWalker(treeStream);
tw.compilationUnit();
知道为什么要输入吗?当我只想获得$variableType.text
属性时,TokenStream解析为空?
这是因为在树语法中,生成规则返回没有text
属性(或GetText()
方法)的TreeRuleReturnScope
。
如果您想获取variableType
规则的文本,则需要显式返回string
。
演示:
SGL.g
grammar SGL;
options {
language=CSharp2;
output=AST;
}
tokens {
VARDEF;
}
@parser::namespace { SGL }
@lexer::namespace { SGL }
public compilationUnit
: statement+ EOF
;
statement
: variableDefinitionList
;
variableDefinitionList
: variableType variableName '=' expression
-> ^(VARDEF variableType variableName expression)
;
variableType
: Type
;
variableName
: ID
;
expression
: Int
;
Type
: 'int'
| 'double'
;
Int
: '0'..'9'+
;
ID
: ('a'..'z' | 'A'..'Z')+
;
Space
: ' ' {Skip();}
;
SGLTreeWalker.g
tree grammar SGLTreeWalker;
options {
tokenVocab=SGL;
language=CSharp2;
ASTLabelType=CommonTree;
}
@namespace { SGL }
compilationUnit
: statement+
;
statement
: variableDefinitionList
;
variableDefinitionList
: ^(VARDEF variableType variableName expression)
{Console.WriteLine($variableType.txt);}
;
variableType returns [string txt]
: Type {$txt = $Type.text;} // note that `Type` is still a normal token!
;
variableName
: ID
;
expression
: Int
;
和class:
using System;
using Antlr.Runtime;
using Antlr.Runtime.Tree;
namespace SGL
{
public class Test
{
public static void Main (string[] args)
{
ANTLRStringStream Input = new ANTLRStringStream("int x = 3");
SGLLexer Lexer = new SGLLexer(Input);
CommonTokenStream Tokens = new CommonTokenStream(Lexer);
SGLParser parser = new SGLParser(Tokens);
CommonTree t = (CommonTree) parser.compilationUnit().Tree;
CommonTreeNodeStream treeStream = new CommonTreeNodeStream(t);
SGLTreeWalker tw = new SGLTreeWalker(treeStream);
tw.compilationUnit();
}
}
}
产生以下输出:
int