[antlr-interest] Island grammar for reading shell commands
Bill Lear
rael at zopyra.com
Tue Nov 30 14:52:11 PST 2010
On Tuesday, November 30, 2010 at 13:07:57 (-0800) Terence Parr writes:
>Wow. input.LT(1) or LT(-1) is returning null.
>
>I'd turn on -trace option of antlr then recompile and retry. that may say more
Here's the output with -trace turned on:
enter SHELL s line=1:0
Got shell. Going native.
enter REST_OF_LINE line=1:5
exit REST_OF_LINE c line=2:0
enter shell [@-1,0:0='<no text>',<-1>,0:-1]
exit shell [@-1,0:0='<no text>',<-1>,0:-1]
exit SHELL c line=2:0
Exception in thread "main" java.lang.NullPointerException
at org.antlr.runtime.Parser.getMissingSymbol(Parser.java:70)
at org.antlr.runtime.BaseRecognizer.recoverFromMismatchedToken(BaseRecognizer.java:604)
at org.antlr.runtime.BaseRecognizer.match(BaseRecognizer.java:115)
at ShellParser.shell(ShellParser.java:49)
at CommandLexer.mSHELL(CommandLexer.java:58)
at CommandLexer.mTokens(CommandLexer.java:712)
at org.antlr.runtime.Lexer.nextToken(Lexer.java:84)
at org.antlr.runtime.CommonTokenStream.fillBuffer(CommonTokenStream.java:95)
at org.antlr.runtime.CommonTokenStream.LT(CommonTokenStream.java:238)
at org.antlr.runtime.Parser.traceIn(Parser.java:92)
at CommandParser.commands(CommandParser.java:47)
at Command.main(Command.java:8)
I posted the grammars previously, but just case you missed them, I posted
them (Shell.g, Command.g) below.
Bill
// Grammar for 'shell ...' command
grammar Shell;
@parser::members {
private String command;
public String getCommand() {
return command;
}
}
shell: REST_OF_LINE {
command = $REST_OF_LINE.text.trim();
}
;
REST_OF_LINE: (options {greedy=false;} : . )* '\r'? '\n' {
emit(Token.EOF_TOKEN);
}
;
// Grammar for other, regular commands
grammar Command;
@lexer::members {
public static final int SHELL_CHANNEL = 1;
}
commands : command+ ;
command
scope {
int timeout;
List<String> notifyList;
}
@init {
$command::timeout = -1;
$command::notifyList = new ArrayList<String>();
}
: cleanup | cleanlog {
}
| SHELL
| NEWLINE
;
cleanup
: CLEANUP command_options? {
System.out.println("cleanup::timeout=" + $command::timeout
+ " email=" + $command::notifyList);
}
;
cleanlog
: CLEANLOG command_options? {
System.out.println("cleanlog::timeout=" + $command::timeout
+ " email=" + $command::notifyList);
}
;
SHELL
: 'shell' {
System.out.println("Got shell. Going native.");
ShellLexer l = new ShellLexer(input);
CommonTokenStream tokens = new CommonTokenStream(l);
ShellParser parser = new ShellParser(tokens);
parser.shell();
String command = parser.getCommand();
System.out.println("Got command from ShellParser:[" + command + "]");
$channel = SHELL_CHANNEL;
}
;
command_options
: timeoutOption
| notifyOption
| timeoutOption notifyOption
| notifyOption timeoutOption
;
timeoutOption
: TIMEOUT INT { $command::timeout = Integer.parseInt($INT.text); }
;
notifyOption
: NOTIFY EMAIL {
$command::notifyList.add($EMAIL.text);
}
| NOTIFY QUOTED_STRING {
String[] l = $QUOTED_STRING.text.split("\\s+");
for (int i = 0; i < l.length; i++) {
$command::notifyList.add(l[i]);
}
}
;
CLEANUP: 'cleanup' ;
CLEANLOG: 'cleanlog' ;
TIMEOUT: '-timeout' ;
NOTIFY: '-notify' ;
INT: '0'..'9'+ ;
QUOTED_STRING:
'"' ( ESCAPE_SEQUENCE | ~('\\'|'"') )* '"' {
setText(getText().substring(1, getText().length() - 1));
}
| '\'' ( ESCAPE_SEQUENCE | ~('\\'|'\'') )* '\'' {
setText(getText().substring(1, getText().length() - 1));
}
;
WS: (' ' | '\t')+ { skip(); } ;
NEWLINE: '\r'? '\n' { } ;
EMAIL: ~('\n' | '\r' | ' ' | '"')+ {
}
;
COMMENT
: '//' ~('\n'|'\r')* '\r'? '\n' { skip(); }
| '/*' ( options {greedy=false;} : . )* '*/' { skip(); }
;
fragment
ESCAPE_SEQUENCE : '\\' ('\"'|'\''|'\\') ;
More information about the antlr-interest
mailing list