假设您要解析包含以空格分隔的数字的平面文本文件.你想把它解析成一个二维数组,int其中每一行都是数组中的"行".
这种"语言"的ANTLR语法可能如下所示:
grammar Number;
parse
: line* EOF
;
line
: Number+ (LineBreak | EOF)
;
Number
: ('0'..'9')+
;
Space
: (' ' | '\t') {skip();}
;
LineBreak
: '\r'? '\n'
| '\r'
;
Run Code Online (Sandbox Code Playgroud)
现在,你想有parse规则返回List的List<Integer>对象.通过returns [List<List<Integer>> numbers]在parse可以在@init{ ... }块中初始化的规则之后添加a来执行此操作:
parse returns [List<List<Integer>> numbers]
@init {
$numbers = new ArrayList<List<Integer>>();
}
: line* EOF
;
Run Code Online (Sandbox Code Playgroud)
您的line规则看起来有点相同,只返回一维数字列表:
line returns [List<Integer> row]
@init {
$row = new ArrayList<Integer>();
}
: Number+ (LineBreak | EOF)
;
Run Code Online (Sandbox Code Playgroud)
下一步是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)
;
Run Code Online (Sandbox Code Playgroud)
最后,您需要添加规则List返回的s,line以便numbers从parse规则中实际添加到2D 列表中:
parse returns [List<List<Integer>> numbers]
@init {
$numbers = new ArrayList<List<Integer>>();
}
: (line {$numbers.add($line.row);})* EOF
;
Run Code Online (Sandbox Code Playgroud)
以下是最终语法:
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'
;
Run Code Online (Sandbox Code Playgroud)
可以使用以下类进行测试:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在从语法中生成词法分析器和解析器:
java -cp antlr-3.2.jar org.antlr.Tool Number.g
Run Code Online (Sandbox Code Playgroud)
编译所有.java源文件:
javac -cp antlr-3.2.jar *.java
Run Code Online (Sandbox Code Playgroud)
并运行主类:
// On *nix
java -cp .:antlr-3.2.jar Main
// or Windows
java -cp .;antlr-3.2.jar Main
Run Code Online (Sandbox Code Playgroud)
产生以下输出:
[[1, 2], [3, 4, 5, 6, 7], [8], [9, 10, 11]]
Run Code Online (Sandbox Code Playgroud)
HTH
| 归档时间: |
|
| 查看次数: |
2519 次 |
| 最近记录: |