在简单整数列表语法中使用 AntLR4 中的访问者 [英] Using Visitors in AntLR4 in a Simple Integer List Grammar

查看:22
本文介绍了在简单整数列表语法中使用 AntLR4 中的访问者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 AntLR 的新手.我使用的是 AntLR4 版本.

I'm a newbie in AntLR. I'm using AntLR4 version.

我编写了以下属性语法,用于识别整数列表并在末尾打印列表的总和.

I wrote the following attribute grammar that recognizes a list of integers and print the sum of the list at the end.

list.g4

grammar list;

@header
{
    import java.util.List;
    import java.util.ArrayList;
}

list
    : BEGL (elems[new ArrayList<Integer>()])? ENDL
        {   
            int sum = 0;
            if($elems.text != null)
                for(Integer i : $elems.listOut)
                    sum += i;
            System.out.println("List Sum: " + sum);
        }
;

elems [List<Integer> listIn] returns [List<Integer> listOut]
    : a=elem (SEP b=elem
            { listIn.add($b.value); }
        )*
            {
                listIn.add($a.value);
                $listOut = $listIn;
            }
;

elem returns [int value]
    : NUM { $value = $NUM.int; }
;

BEGL : '[';
ENDL : ']';
SEP : ',';
NUM : [0-9]+;
WS : (' '|'\t'|'\n')+ -> skip;

一个有效的输入是:

[1, 2, 3]

为了测试我的语法,我使用了 TestRig 工具.

For testing my grammar, I'm using TestRig Tool.

现在,我想使用访问者来清楚地将代码与语法分开.

我知道我需要使用带有 -visitor 选项的 antlr 来为我的应用程序生成访问者类.

I know that I need to use antlr with the -visitor option to generate the Visitor class for my application.

我想知道如何在访问者方法类中访问给定产品的属性,以及如何将词法分析器、解析器和访问者代码片段粘合"在一起.

I would like to know how to access the atrributes of a given production in the Visitor methods class and how to "glue" the lexer, parser and visitor code pieces together.

推荐答案

你的语法没有动作,并且在 WS 规则中包含 \r :

Your grammar without actions, and including \r in the WS rule:

grammar list;

list
 : BEGL elems? ENDL
 ;

elems
 : elem ( SEP elem )*
 ;

elem
 : NUM
 ;

BEGL : '[';
ENDL : ']';
SEP  : ',';
NUM  : [0-9]+;
WS   : [ \t\r\n]+ -> skip;

访问者可能看起来像这样:

The visitor could then look like this:

public class SumVisitor extends listBaseVisitor<Integer> {

    @Override
    public Integer visitList(@NotNull listParser.ListContext ctx) {
        return ctx.elems() == null ? 0 : this.visitElems(ctx.elems());
    }

    @Override
    public Integer visitElems(@NotNull listParser.ElemsContext ctx) {
        int sum = 0;
        for (listParser.ElemContext elemContext : ctx.elem()) {
            sum += this.visitElem(elemContext);
        }
        return sum;
    }

    @Override
    public Integer visitElem(@NotNull listParser.ElemContext ctx) {
        return Integer.valueOf(ctx.NUM().getText());
    }
}

并且可以进行如下测试:

and can be tested as follows:

listLexer lexer = new listLexer(new ANTLRInputStream("[1, 2, 3]"));
listParser parser = new listParser(new CommonTokenStream(lexer));
Integer sum = new SumVisitor().visit(parser.list());
System.out.println("sum=" + sum);

将打印:

sum=6

这篇关于在简单整数列表语法中使用 AntLR4 中的访问者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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