[antlr-interest] handling include files

Mark Venbrux mark.venbrux at gmail.com
Thu Sep 7 23:36:14 PDT 2006


Hi,

I figured out a way with little impact to handle include files... But
it is different from the suggested approach in this mailing list. It
is shown in the simple grammar below, so please comment.
An issue that pops up when handling include file is that the source of
an error in the parsed input becomes less clear. So I added an
'ExtCommonToken' class that shows the input source name in its
toString() method.
Is this a decent approach? Or are there better ways?
Cheers,
Mark
-


grammar Simple;
@parser::members {
    	public void reportError(RecognitionException e) {
    		if ( e.input instanceof ANTLRFileStream ) {
    			System.err.print("File: '" +
    					   ((ANTLRFileStream)e.input).getSourceName() +"'");
    		}

    		super.reportError(e);
    	}

}
@lexer::header {
import java.io.IOException;
}
@lexer::members {
        protected java.util.Stack<CharStream> includeStack = new
java.util.Stack<CharStream>();
	public void EnterInclude(CharStream include) {
		includeStack.push(this.input);
		this.input = include;
		skip();
	}

	/** Return a token from this source; i.e., match a token on the char
	 *  stream. Pop the include stack upon EOF.
	 */
	public Token nextToken() {
		// First pop the include stack as far as needed...
		while (input.LA(1) == CharStream.EOF && !includeStack.empty()) {
			input = includeStack.pop();
		}		
		return super.nextToken();
	}
	/** The standard method called to automatically emit a token at the
	 *  outermost lexical rule.  The token object should point into the
	 *  char buffer start..stop.  If there is a text override in 'text',
	 *  use that to set the token's text.
	 */
	public Token emit(int tokenType,
			  int line, int charPosition,
			  int channel,
			  int start, int stop)
	{
		Token t = new ExtCommonToken(input, tokenType, channel, start, stop);
		t.setLine(line);
		t.setText(text);
		t.setCharPositionInLine(charPosition);
		emit(t);
		return t;
	}	
	
    	public void reportError(RecognitionException e) {
    		if ( e.input instanceof ANTLRFileStream ) {
    			System.err.print("File: '" +
 				((ANTLRFileStream)e.input).getSourceName() +"'");
    		}

    		super.reportError(e);
    	}

}
program : (variable)*
        ;
variable: 'int' ID ('=' INT)? ';'
        ;



ID      : ('a'..'z'|'A'..'Z')+ ;
INT     : ('0'..'9')+ ;
WS      : (' '|'\t'|'\n')+ {channel=99;}
        ;
protected
StringLiteral
    :  '"' (  ~('"') )* '"'
    ;


INCLUDE : '#include' WS* fileNameToken=StringLiteral WS* ';' {channel=99;}
{
    String fileName = $fileNameToken.getText().substring(1,
$fileNameToken.getText().length()-1);
    System.out.println("enter include: " + fileName);
    CharStream includedFile = null;
    try {
    	includedFile = new ANTLRFileStream(fileName);
    } catch (IOException e) {
    	e.printStackTrace();
    }
    EnterInclude(includedFile);
}
    ;



-- 
Mvg,
    Mark


More information about the antlr-interest mailing list