views:

99

answers:

2

I need to parse the command shell such as:

cp /home/test /home/test2

My problem is in the correct path parsing.

I defined a rule (I can not use a token as path but I need to define it in the parser):

path : ('/' ID)+;

with

ID: (A.. Z | a.. z) +;
WS: (' ') {$channel = HIDDEN;};

I need to keep the token WS hidden, but this gives me the problem that the 2 paths in this example are considered as a single path.

How can I solve this problem?

Thanks

A: 

With a little playing around in ANTLRWorks I was able to get this to work:

commands
    :   command+ EOF;

command
    :   (CMD first=path second=path '\n') {System.out.println("Command found, first path:" + $first.text + ", and second path:" + $second.text + "\n");};

path : FILE {System.out.println("file is:" + $FILE.text);};

fragment
ID: ('A'..'Z'|'a'..'z')('A'..'Z'|'a'..'z'|'0'..'9')+;
CMD
    :   ID;
FILE 
    :   ('/' ID)+;
WS: (' '|'\t'|'\r'|'\n') {$channel = HIDDEN;};

Please notice that I had to create a few more lexer rules and then start putting different parser rules to test. I used a java target and will let you use what ever target you want.

Oh yeah, each command has to be on a separate line because of the '\n' in the command rule.

WayneH
I think you are wanting to expand the command rule now, something like:command : 'cp' first=path second=path '\n' {...}|'del' path {... you only have one path for this rule to use in your action}|'compare' first=path second=path third=path {in here place your code to compare the first with the second and place in the third};Of course, this would also make the CMD lexer rule useless (not required). But there could be other ways to make these work as well.
WayneH
ok, I appreciate the quick answer, but in my case it doesn't work, since other rules impose me to NOT define the path as a token (FILE).Starting from my code (with the path NOT defined as a single token) it's possible to use the whitespace (hidden token) as a separator?
Nio
A: 

Ok, based on your comment, how about something like this:

commands
    :   command+ EOF;

command
    :   (ID ' ' (path)+ ' ' (path)+ '\n') {System.out.println("Command found:" + $command.text + "\n");};

path : 
    ('/' ID)+ {System.out.println("path is:" + $path.text);};

ID: ('A'..'Z'|'a'..'z')('A'..'Z'|'a'..'z'|'0'..'9')+;
WS: (' '|'\t'|'\r'|'\n') {$channel = HIDDEN;};

Again, I was able to get this working in ANTLRWorks quickly and it appears to work with the cp command listed above. But pesonally I don't like this as much since your path is a list of four tokens and quickly I could not split out easily. So, you might require a rule between command and path (since I would assume your shell command might have some commands that work with files while others work on directories).

I am also hoping the ID and WS lexer rules are what you want.

WayneH