Quick actions

cmd+k|ctrl+k

Navigation

Languages

reddit "lexer modes parser advancingpeeking" 

Snippet info

Language

Raku

Visibility

public

Author

raiph

Created

2018-09-27T19:26:32Z

Updated

2023-09-25T00:35:33.451592Z

    # See https://www.reddit.com/r/ProgrammingLanguages/comments/9j9r97/lexer_modes_parser_token_advancingpeeking/e6r2k7c
    # use Grammar::Tracer;

    my @args;  # Store arguments to ease into showing P6 is building a complete parse tree

    grammar string { ... } # stub declaration because grammars recursively call each other

    grammar mainline-code {
      rule TOP           { <statement>* %% \n+ }                 # %% RHS is separator
      token statement    { <routine-call>? <eol-comment>? }
      token routine-call { <method-call> | <sub-call> }
      token method-call  { <ident> '.' <ident> }
      token sub-call     { <ident> \s+ <argument>* % ',' }       # % means ',' only in between 
      token argument     {
        [ | <number>
          | <variable>
          | <string::TOP>       # Recursively call string grammar
        ]
        # Hack to hint that parse tree is being built:  
        { @args.append: .keys, .Str given $/ } 
      }
      token variable     { '$' <ident> }
      token number       { \d+ }
      token eol-comment  { '#' \N* }
    }

    grammar string {
      rule TOP { \" ~ \" <content>* }       # `~` looks between LHS/RHS operands for content 
      token content {
        || <mainline-code::variable>        # Reuse mainline-code grammar parsing for variable
        || <before '$({'> <embedded-code>   # `before` peeks ahead
        || .                                # Otherwise munch a single character
      }
      # Recursively call mainline grammar in attempt to parse code block embedded in string: 
      rule embedded-code { '$({' ~ '})' <mainline-code::TOP> }
    }
    
    (.say for @args) given mainline-code.parse: q:to<EOS>;
      println "it is $({
          # This is a comment!?
          sleep 250
          date.now
      }) right now!"
      EOS
      
    say mainline-code.parse: 'println "hello $person!"';
INFO