[antlr-interest] Island grammar for reading shell commands
Jim Idle
jimi at temporal-wave.com
Tue Nov 30 15:49:39 PST 2010
REST_OF_LINE allows an empty token which will immediately match nothing and
continue to do so forever. You want + not *. I think you might be doing
this wrong to be honest. I would probably not use ANTLR for this.
Jim
> -----Original Message-----
> From: antlr-interest-bounces at antlr.org [mailto:antlr-interest-
> bounces at antlr.org] On Behalf Of Bill Lear
> Sent: Tuesday, November 30, 2010 2:52 PM
> To: Terence Parr
> Cc: antlr-interest at antlr.org
> Subject: Re: [antlr-interest] Island grammar for reading shell commands
>
> 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(BaseRecogni
> zer.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:9
> 5)
> 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 : '\\' ('\"'|'\''|'\\') ;
>
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-
> email-address
More information about the antlr-interest
mailing list