Antlr4 - 是否有使用ParseTree Walker的简单示例? [英] Antlr4 - Is there a simple example of using the ParseTree Walker?

查看:252
本文介绍了Antlr4 - 是否有使用ParseTree Walker的简单示例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Antlr4有一个新类ParseTreeWalker。但是我该如何使用它?我正在寻找一个最小的工作示例。我的语法文件是'gram.g4',我想解析文件'program.txt'



这是我的代码到目前为止。 (这假定ANTLR运行了我的语法文件并创建了所有 gramBaseListener gramLexer 等):

  import org.antlr.v4.runtime。*; 
import org.antlr.v4.runtime.tree。*;
import static org.antlr.v4.runtime.CharStreams.fromFileName;

公共类启动{
public static void main(String [] args){

CharStream cs = fromFileName(gram.g4); //加载文件
gramLexer lexer = new gramLexer(cs); //实例化词法分析器
CommonTokenStream tokens = new CommonTokenStream(词法分析器); //用于标记的扫描流
gramParser parser = new gramParser(tokens); //解析标记

//现在是什么?如何将以上内容连接到下面?

ParseTreeWalker walker = new ParseTreeWalker(); //如何使用它来解析program.txt?
}}

我使用的是java,但我认为它与其他语言类似。



ANTLR文档( http: //www.antlr.org/api/Java/index.html )是简短的例子。互联网上有许多教程但它们主要用于ANTLR版本3.使用版本4的少数教程不起作用或过时(例如,没有parser.init()函数,并且像ANTLRInputStream这样的类被折旧)



提前感谢任何可以提供帮助的人。

解决方案

您的语法中的解析器规则,生成的解析器将具有该名称的相应方法。调用该方法将开始解析该规则。



因此,如果您的根规则命名为 start ,那么您将开始通过<$ c $解析c> gramParser.start(),它返回 ParseTree 。然后可以将此树与您想要使用的侦听器一起输入 ParseTreeWalker



总而言之,它看起来像这样(EDITED BY OP):

  import org.antlr.v4.runtime。*; 
import org.antlr.v4.runtime.tree。*;
import static org.antlr.v4.runtime.CharStreams.fromFileName;

公共类启动{
public static void main(String [] args){

CharStream cs = fromFileName(program.txt); //加载文件
gramLexer lexer = new gramLexer(cs); //实例化词法分析器
CommonTokenStream tokens = new CommonTokenStream(词法分析器); //用于标记的扫描流
gramParser parser = new gramParser(tokens); //解析标记

ParseTree tree = parser.start(); //解析内容并获取树
Mylistener listener = new Mylistener();

ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(听众,树);
}}

************新文件Mylistener .java ************

 公共类Mylistener扩展了gramBaseListener {
@Override public void enterEveryRule(ParserRuleContext ctx){//请参阅允许函数的gramBaseListener
System.out.println(rule entered:+ ctx.getText()); //按规则执行的代码
}
}

当然你有使用 BaseListener



<的实现替换< listener> 并且只有一个小的sidenode:在Java中,通常用大写字母开始类名,我建议你坚持这样做,以使代码对其他人更具可读性。


Antlr4 has a new class ParseTreeWalker. But how do I use it? I am looking for a minimal working example. My grammar file is 'gram.g4' and I want to parse a file 'program.txt'

Here is my code so far. (This assumes ANTLR has run my grammar file and created all of the gramBaseListener, gramLexer, etc etc):

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
import static org.antlr.v4.runtime.CharStreams.fromFileName;

public class launch{
public static void main(String[] args) {

    CharStream cs = fromFileName("gram.g4");  //load the file
    gramLexer lexer = new gramLexer(cs);  //instantiate a lexer
    CommonTokenStream tokens = new CommonTokenStream(lexer); //scan stream for tokens
    gramParser parser = new gramParser(tokens);  //parse the tokens

    // Now what??  How do I connect the above with the below? 

    ParseTreeWalker walker = new ParseTreeWalker();  // how do I use this to parse program.txt??
}}

I am using java but I assume it is similar in other languages.

The ANTLR documentation (http://www.antlr.org/api/Java/index.html) is short on examples. There are many tutorials on the internet but they are mostly for ANTLR version 3. The few using version 4 don't work or are outdated (for example, there is no parser.init() function, and classes like ANTLRInputStream are depreciated)

Thanks in advance for anyone who can help.

解决方案

For each of your parser rules in your grammar the generated parser will have a corresponding method with that name. Calling that method will start parsing at that rule.

Therefore if your "root-rule" is named start then you'd start parsing via gramParser.start() which returns a ParseTree. This tree can then be fed into the ParseTreeWalker alongside with the listener you want to be using.

All in all it could look something like this (EDITED BY OP):

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
import static org.antlr.v4.runtime.CharStreams.fromFileName;

public class launch{
public static void main(String[] args) {

    CharStream cs = fromFileName("program.txt");  //load the file
    gramLexer lexer = new gramLexer(cs);  //instantiate a lexer
    CommonTokenStream tokens = new CommonTokenStream(lexer); //scan stream for tokens
    gramParser parser = new gramParser(tokens);  //parse the tokens

    ParseTree tree = parser.start(); // parse the content and get the tree
    Mylistener listener = new Mylistener();

    ParseTreeWalker walker = new ParseTreeWalker();
    walker.walk(listener,tree);
}}

************ NEW FILE Mylistener.java ************

public class Mylistener extends gramBaseListener {
        @Override public void enterEveryRule(ParserRuleContext ctx) {  //see gramBaseListener for allowed functions
            System.out.println("rule entered: " + ctx.getText());      //code that executes per rule
        }
    }

Of course you have to replace <listener> with your implementation of BaseListener

And just one small sidenode: In Java it is convention to start classnames with capital letters and I'd advise you to stick to that in order for making the code more readable for other people.

这篇关于Antlr4 - 是否有使用ParseTree Walker的简单示例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆