Search code examples
parsingraku

Partial matching in a simple Raku program


I've created a simple program based on the Raku parsefile example provided here. The contents of my Raku file are:

grammar Names {
  token TOP  { [<name><.ws>]+ }
  token name { <:alpha>+ }
}                                                                               
                                                                                
say Names.parsefile('names.txt');

The contents of names.txt is below:

Andrea
John

Running this minimal program indicates a successful parse has been achieved:

「Andrea
John
」
 name => 「Andrea」
 name => 「John」

If I now add something which will not be parsed by the name token (i.e. 99999999):

Andrea
99999999
John

...running the program then outputs only Nil. Is there a way to modify the program so that I could still find that "Andrea" and "John" have been parsed by the name token successfully?


Solution

  • Probably comb, match or contains is better in your case.

    my token name { <:alpha>+ };
    
    say './raku/names.txt'.IO.comb(/<name>/);
    say slurp('./raku/names.txt').match(/<name>/,:g);
    say './raku/names.txt'.IO.words.grep: *.contains: /^<name>$/;
    
    (Andrea John)
    (「Andrea」
     name => 「Andrea」 「John」
     name => 「John」)
    (Andrea John)
    

    If you really want grammar, you could redefine <ws>.

    grammar Names {
        rule TOP  { ^ <name> +  }
        token name { <:alpha>+ }
        token ws { <-alpha>* }
        #or more general  token ws { [<!before <name>>.]* }
    }
    
    say Names.parsefile: './raku/names.txt';
    
    「Andrea
    99999999
    John
    」
     name => 「Andrea」
     name => 「John」