简体   繁体   中英

Antlr syntactic predicate no matching

I have the following grammar:

rule  : (PATH)=> (PATH) SLASH WORD
   {System.out.println("file: " + $WORD.text + " path: " + $PATH.text);};
WORD  : ('a'..'z')+;
SLASH   : '/';
PATH    : (WORD SLASH)* WORD;

but it does not work for a string like "a/b/c/filename". I thought I could solve this "path"-problem with the syntactic predicate feature. Maybe I am doing something wrong here and I have to redefine the grammar. Any suggestion for this problem?

You must understand that a syntactic predicate will not cause the parser to give the lexer some sort of direction wrt what token the parser would "like" to retrieve. A syntactic predicate is used to force the parser to look ahead in an existing token stream to resolve ambiguities (emphasis on 'existing': the parser has no control over what token are created!).

The lexer operates independently from the parser, creating tokens in a systematic way:

  1. it tries to match as much characters as possible;
  2. whenever 2 (or more) rules match the same amount of characters, the rule defined first will get precedence over the rule(s) defined later.

So in your case, given the input "a/b/c/filename" , the lexer will greedily match the entire input as a single PATH token.

If you want to get the file name, either retrieve it from the PATH :

rule  : PATH
        {
         String file = $PATH.text.substring($PATH.text.lastIndexOf('/') + 1);
         System.out.println("file: " + file + ", path: " + $PATH.text);
        }
      ;
WORD  : ('a'..'z')+;
SLASH : '/';
PATH  : (WORD SLASH)* WORD;

or create a parser rule that matches a path:

rule  : dir WORD
        {
         System.out.println("file: " + $WORD.text + ", dir: " + $dir.text);
        }
      ;
dir   : (WORD SLASH)+;
WORD  : ('a'..'z')+;
SLASH : '/';

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM