嘿香港专业教育学院开始使用Antlr与java,我想知道如何将一些值直接存储到2d数组并返回此数组?我根本找不到这方面的任何教程,所有的帮助都得到了解释。
答案 0 :(得分:7)
假设您要解析包含以空格分隔的数字的平面文本文件。您想将其解析为int
的二维数组,其中每一行都是数组中的“行”。
这种“语言”的ANTLR语法可能如下所示:
grammar Number;
parse
: line* EOF
;
line
: Number+ (LineBreak | EOF)
;
Number
: ('0'..'9')+
;
Space
: (' ' | '\t') {skip();}
;
LineBreak
: '\r'? '\n'
| '\r'
;
现在,您希望parse
规则返回List
个List<Integer>
个对象。通过在returns [List<List<Integer>> numbers]
规则之后添加parse
来实现这一点,该规则可以在@init{ ... }
块中初始化:
parse returns [List<List<Integer>> numbers]
@init {
$numbers = new ArrayList<List<Integer>>();
}
: line* EOF
;
您的line
规则看起来有点相同,只返回一维数字列表:
line returns [List<Integer> row]
@init {
$row = new ArrayList<Integer>();
}
: Number+ (LineBreak | EOF)
;
下一步是使用正在解析的实际值填充List
s。这可以在{$row.add(Integer.parseInt($Number.text));}
规则的Number+
循环中嵌入代码line
来完成:
line returns [List<Integer> row]
@init {
$row = new ArrayList<Integer>();
}
: (Number {$row.add(Integer.parseInt($Number.text));})+ (LineBreak | EOF)
;
最后,您需要添加List
规则返回的line
,以便从numbers
规则中实际添加到您的2D parse
列表中:
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'
;
可以使用以下类进行测试:
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);
}
}
现在从语法中生成词法分析器和解析器:
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
答案 1 :(得分:0)
以下是我编写的一些语法摘录,用于解析人名并返回Name
个对象。应该足以告诉你它是如何工作的。其他对象(如数组)也以相同的方式完成。
在语法中:
grammar PersonNames;
fullname returns [Name name]
@init {
name = new Name();
}
: (directory_style[name] | standard[name] | title_without_fname[name] | family_style[name] | proper_initials[name]) EOF;
standard[Name name]
: (title[name] ' ')* fname[name] ' ' (mname[name] ' ')* (nickname[name] ' ')? lname[name] (sep honorifics[name])*;
fname[Name name] : (f=NAME | f=INITIAL) { name.set(Name.Part.FIRST, toNameCase($f.text)); };
在常规Java代码中
public static Name parseName(String str) throws RecognitionException {
System.err.println("parsing `" + str + "`");
CharStream stream = new ANTLRStringStream(str);
PersonNamesLexer lexer = new PersonNamesLexer(stream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
PersonNamesParser parser = new PersonNamesParser(tokens);
return parser.fullname();
}