2011-10-28 68 views
2

我想解析一个文件,其中第一行可能包含或不包含“项目”名称的定义(与Pascal的关键字program一样),如果不是,则使用正在解析的文件的名称作为默认。简体:获取解析文件的名称?

@members{ String projectName; } 

project : {projectName = ...} // name of parsed file as default 
     (PROJECTNAMEKEYWORD ID {projectName = $ID.text;})? 
      otherstuff {/*...*/}; 

这甚至可能吗?我发现使用谷歌或antlr手册很难发现这一点。通过它的文档,input.getSourceName()应该是我正在寻找的东西,但它总是返回null,并且调试将导致我的类ANTLRStringStreamname字段,其​​值由此方法返回但从未设置。

回答

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()); 
    } 
} 

如果您运行的主类,以下将被打印到控制台:

empty.txt 
JustATest