Antlr阵列帮助 [英] Antlr Array Help

查看:66
本文介绍了Antlr阵列帮助的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,我开始在Java中使用Antlr,我想知道如何将一些值直接存储到2d数组中并返回此数组?我根本找不到任何教程,所有帮助都提供了.

Hey ive started to use Antlr with java and i wanted to know how i can store some values directly into a 2d array and return this array? i cant find any tutorials on this at all, all help is apperciated.

推荐答案

假设您要解析一个包含用空格分隔的数字的纯文本文件.您想将其解析为int的二维数组,其中每一行都是数组中的行".

Let's say you want to parse a flat text file containing numbers separated by spaces. You'd like to parse this into a 2d array of int's where each line is a "row" in your array.

此类语言"的ANTLR语法如下:

The ANTLR grammar for such a "language" could look like:

grammar Number;

parse
  :  line* EOF
  ;

line
  :  Number+ (LineBreak | EOF)
  ;

Number
  :  ('0'..'9')+
  ;

Space
  :  (' ' | '\t') {skip();}
  ;

LineBreak
  :  '\r'? '\n'
  |  '\r'
  ;

现在,您希望parse规则返回ListList<Integer>对象.为此,可以在parse规则后添加一个returns [List<List<Integer>> numbers],该规则可以在@init{ ... }块中初始化:

Now, you'd like to have the parse rule return an List of List<Integer> objects. Do that by adding a returns [List<List<Integer>> numbers] after your parse rule which can be initialized in an @init{ ... } block:

parse returns [List<List<Integer>> numbers]
@init {
  $numbers = new ArrayList<List<Integer>>();
}
  :  line* EOF
  ;

您的line规则看起来有点相同,只不过它返回一维数字列表:

Your line rule looks a bit the same, only it returns a 1 dimensional list of numbers:

line returns [List<Integer> row]
@init {
  $row = new ArrayList<Integer>();
}
  :  Number+ (LineBreak | EOF)
  ;

下一步是将要解析的实际值填充到List中.可以将代码{$row.add(Integer.parseInt($Number.text));}嵌入到line规则的Number+循环内:

The next step is to fill the Lists with the actual values that are being parsed. This can be done embedding the code {$row.add(Integer.parseInt($Number.text));} inside the Number+ loop in your line rule:

line returns [List<Integer> row]
@init {
  $row = new ArrayList<Integer>();
}
  :  (Number {$row.add(Integer.parseInt($Number.text));})+ (LineBreak | EOF)
  ;

最后,您需要添加List规则返回的List,以便实际上将其从parse规则添加到2D numbers列表中:

And lastly, you'll want to add the Lists being returned by your line rule to be actually added to your 2D numbers list from your parse rule:

parse returns [List<List<Integer>> numbers]
@init {
  $numbers = new ArrayList<List<Integer>>();
}
  :  (line {$numbers.add($line.row);})* EOF
  ;

下面是最终的语法:

grammar Number;

parse returns [List<List<Integer>> numbers]
@init {
  $numbers = new ArrayList<List<Integer>>();
}
  :  (line {$numbers.add($line.row);})* EOF
  ;

line returns [List<Integer> row]
@init {
  $row = new ArrayList<Integer>();
}
  :  (Number {$row.add(Integer.parseInt($Number.text));})+ (LineBreak | EOF)
  ;

Number
  :  ('0'..'9')+
  ;

Space
  :  (' ' | '\t') {skip();}
  ;

LineBreak
  :  '\r'? '\n'
  |  '\r'
  ;

可以通过以下类进行测试:

which can be tested with the following class:

import org.antlr.runtime.*;
import java.util.List;

public class Main {
    public static void main(String[] args) throws Exception {
        String source = 
                "1 2       \n" +
                "3 4 5 6 7 \n" +
                "      8   \n" +
                "9 10 11     ";
        ANTLRStringStream in = new ANTLRStringStream(source);
        NumberLexer lexer = new NumberLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        NumberParser parser = new NumberParser(tokens);
        List<List<Integer>> numbers = parser.parse();
        System.out.println(numbers);
    }
}

现在从语法生成词法分析器和解析器:

Now generate a lexer and parser from the grammar:

java -cp antlr-3.2.jar org.antlr.Tool Number.g

编译所有.java源文件:

javac -cp antlr-3.2.jar *.java

并运行主类:

// On *nix
java -cp .:antlr-3.2.jar Main

// or Windows
java -cp .;antlr-3.2.jar Main

产生以下输出:

[[1, 2], [3, 4, 5, 6, 7], [8], [9, 10, 11]]

HTH

这篇关于Antlr阵列帮助的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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