我从Java语言定义中得到了一个“语句”定义如下。
statement
: block
| ASSERT expression (':' expression)? ';'
| 'if' parExpression statement ('else' statement)?
| 'for' '(' forControl ')' statement
| 'while' parExpression statement
| 'do' statement 'while' parExpression ';'
| 'try' block
( catches 'finally' block
| catches
| 'finally' block
)
| 'switch' parExpression switchBlock
| 'synchronized' parExpression block
| 'return' expression? ';'
| 'throw' expression ';'
| 'break' Identifier? ';'
| 'continue' Identifier? ';'
| ';'
| statementExpression ';'
| Identifier ':' statement
;
在执行解析器时,我还要打印完整的用户编写的语句(包含语句中的空格),例如:
Object o = Ma.addToObj(r1);
if(h.isFull() && !h.contains(true)) h.update(o);
但是当我在“exitStatement”中使用函数“getText()”时,我只能获取删除了所有空格的语句,例如:
Objecto=Ma.addToObj(r1);
if(h.isFull()&&!h.contains(true))h.update(o);
如何以简单的方式获取完整的用户编写语句(包含语句中的空格)?非常感谢!
完整代码如下:
public class PrintStatements {
public static class GetStatements extends sdlParserBaseListener {
StringBuilder statements = new StringBuilder();
public void exitStatement(sdlParserParser.StatementContext ctx){
statements.append(ctx.getText());
statements.append("\n");
}
}
public static void main(String[] args) throws Exception{
String inputFile = null;
if ( args.length>0 ) inputFile = args[0];
InputStream is = System.in;
if ( inputFile!=null ) {
is = new FileInputStream(inputFile);
}
ANTLRInputStream input = new ANTLRInputStream(is);
sdlParserLexer lexer = new sdlParserLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
sdlParserParser parser = new sdlParserParser(tokens);
ParseTree tree = parser.s();
// create a standard ANTLR parse tree walker
ParseTreeWalker walker = new ParseTreeWalker();
// create listener then feed to walker
GetStatements loader = new GetStatements();
walker.walk(loader, tree); // walk parse tree
System.out.println(loader.statements.toString());
}
}
答案 0 :(得分:7)
我通过在语句的上层使用tokens.getText()解决了这个问题,如下所示:
public void exitE(sdlParserParser.EContext ctx) {
TokenStream tokens = parser.getTokenStream();
String Stmt = null;
Stmt = tokens.getText(ctx.statement());
...
}
答案 1 :(得分:0)
我对ANTLR很新,所以也许我错了......
我不知道这样做的简单方法,但你可以尝试这样的事情。 在你的语法文件中,你可能有这样的东西:
WS : (' '|'\r'|'\t'|'\u000C'|'\n')
{
if (!preserveWhitespacesAndComments) {
skip();
} else {
$channel = HIDDEN;
}
}
此词法分析器规则告诉解析器忽略空格。更确切地说,这些令牌是在HIDDEN通道上发送的(解析器看不到它们)。如果你评论这行代码
WS : (' '|'\r'|'\t'|'\u000C'|'\n')
{
if (!preserveWhitespacesAndComments) {
// skip();
} else {
// $channel = HIDDEN;
}
}
所有空格都将被发送到解析器,但是您需要重写解析器规则,以便他可以在任何地方获得空格。
Object(EXPECT WHITESPACE)o(EXPECT WHITESPACE)=(EXPECT WHITESPACE)Ma.addToObj(r1);
否则解析器将报告错误。
答案 2 :(得分:0)
您需要以下两种方法之一:
答案 3 :(得分:0)
就Antlr4和Python3而言,code如下所示:
def exitSomeDecl(self, ctx: yourParser.SomeDeclContext):
start_index = ctx.start.tokenIndex
stop_index = ctx.stop.tokenIndex
user_text = self.token_stream.getText(interval=(start_index, stop_index))
此处,self.token_stream: CommonTokenStream
在init期间分配:
input_stream = FileStream(file_name)
lexer = sdplLexer(input_stream)
token_stream = CommonTokenStream(lexer)