我想解析一个文件,其中第一行可能包含或不包含“项目”名称的定义(与Pascal的program
关键字一样),如果没有,请使用该文件的名称正在被解析为默认值。简化为:
@members{ String projectName; }
project : {projectName = ...} // name of parsed file as default
( PROJECTNAMEKEYWORD ID {projectName = $ID.text;} )?
otherstuff {/*...*/};
这甚至可能吗?我发现这很难找到使用谷歌或antlr手册。通过它的文档,input.getSourceName()
应该是我正在寻找的,但它总是返回null,并且调试引导我到具有ANTLRStringStream
字段的类name
,其值由此返回方法但从未设定。
答案 0 :(得分:3)
只需在解析器中创建一个自定义构造函数,该构造函数接受一个代表您文件的字符串。
演示:
grammar T;
@parser::members {
private String projectName;
public TParser(String fileName) throws java.io.IOException {
super(new CommonTokenStream(new TLexer(new ANTLRFileStream(fileName))));
projectName = fileName;
}
public String getProjectName() {
return projectName;
}
}
parse
: (PROJECT ID {projectName = $ID.text;})? EOF
;
PROJECT : 'project';
ID : ('a'..'z' | 'A'..'Z')+;
SPACE : (' ' | '\t' | '\r' | '\n') {skip();};
可以用以下方法测试:
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
// 'empty.txt' is, as the name suggests, an empty file
TParser parser = new TParser("empty.txt");
parser.parse();
System.out.println(parser.getProjectName());
// 'test.txt' contains a single line with the words: 'project JustATest'
parser = new TParser("test.txt");
parser.parse();
System.out.println(parser.getProjectName());
}
}
如果您运行Main类,则会在控制台上打印以下内容:
empty.txt
JustATest