use lib '.';
use Apostolique;
for 1,2,3,4 {
say "Example $_\n=========\n";
say .&slurp;
say "\nParses to\n=========\n";
for Apostolique-Grammar.parse(.&slurp).<chunk> {
say |.chunks.grep: *.key ne 'whitespace'
}
say "\n"
}
#use Grammar::Tracer;
grammar Apostolique-Grammar {
token TOP { <chunk>* }
token chunk { <whitespace> || <code> || <comment> }
token whitespace { \s+ }
rule code { 'int' <.ident> '=' <.digit>+ ';'}
token comment {
|| <.slc>
|| :my $*mlc-level = 0; <.mlc>
}
token slc { '//' [ <!before '*/'> <-[\n]> ]* <!before '*/'> }
token mlc { <.mlc-open> <.mlc-middle> <.mlc-close> }
token mlc-open {
|| '/*' {$*mlc-level++} # real mlc
|| <!{$*mlc-level}> {$*mlc-level = 0.5} # signal fake mlc
}
token mlc-close(:$leave-level-alone?) {
|| '*//' {$*mlc-level = -1} # signal mlc breakout
|| <?{$*mlc-level == -1}> # accept mlc breakout
|| '*/' {$*mlc-level-- unless $leave-level-alone}
}
token mlc-middle {
[
|| <mlc>
|| <!before <mlc-close(:leave-level-alone)>>
[
|| <?{$*mlc-level < 1}> <-[\n]> # fake mlc?
|| <?{$*mlc-level >= 1}> . # real mlc
]
]*
}
}
/* Hello /* World */*/
/*
/*
/*
Comment here
*//
// single line comment
int a = 10;
/* multiline comment
multiline catch or single line backwards */
int b = 20;
multiline catch or single line backwards */
int a = 10; // backwards wins! */ int b = 20;