grammar to ebnf
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
use experimental :rakuast;
multi sub ebnf(RakuAST::StatementList:D $ast --> Str:D) {
$ast.statements.map({ ebnf($_) }).join("\n")
}
multi sub ebnf(RakuAST::Statement::Expression:D $ast --> Str:D) {
ebnf($ast.expression)
}
sub name-of(RakuAST::Name:D $name --> Str:D) {
$name.simple-identifier
}
multi sub ebnf(RakuAST::Grammar:D $ast --> Str:D) {
my $name = name-of($ast.name);
my $body = ebnf($ast.body);
"$name \{\n$body\n\}"
}
multi sub ebnf(RakuAST::Block:D $ast --> Str:D) {
ebnf($ast.body)
}
multi sub ebnf(RakuAST::Blockoid:D $ast --> Str:D) {
ebnf($ast.statement-list)
}
multi sub ebnf(RakuAST::TokenDeclaration:D $ast --> Str:D) {
my $name = name-of($ast.name);
my $body = ebnf($ast.body);
"$name = $body ;"
}
multi sub ebnf(RakuAST::Regex::WithWhitespace:D $ast --> Str:D) {
ebnf($ast.regex)
}
multi sub ebnf(RakuAST::Regex::QuantifiedAtom:D $ast --> Str:D) {
my $atom = ebnf($ast.atom);
given $ast.quantifier {
when RakuAST::Regex::Quantifier::OneOrMore {
"$atom, \{ $atom \}"
}
when RakuAST::Regex::Quantifier::ZeroOrMore {
"\{ $atom \}"
}
when RakuAST::Regex::Quantifier::ZeroOrOne {
"[ $atom ]"
}
default {
die "Unsupported quantifier: {$ast.quantifier.^name}";
}
}
}
multi sub ebnf(RakuAST::Regex::Assertion::Named:D $ast --> Str:D) {
name-of $ast.name
}
multi sub ebnf(RakuAST::Regex::SequentialAlternation:D $ast --> Str:D) {
$ast.branches.map({ ebnf($_) }).join(" | ")
}
multi sub ebnf(RakuAST::Regex::Assertion::CharClass:D $ast --> Str:D) {
$ast.elements.map({ ebnf($_) }).join(" | ")
}
multi sub ebnf(
RakuAST::Regex::CharClassElement::Enumeration:D $ast
--> Str:D
) {
$ast.elements.map({ ebnf($_) }).join(" | ")
}
multi sub ebnf(
RakuAST::Regex::CharClassEnumerationElement::Character:D $ast
--> Str:D
) {
'"' ~ $ast.character ~ '"'
}
multi sub ebnf(Mu:D $ast --> Str:D) {
die "UNHANDLED AST NODE: {$ast.^name}";
}
say ebnf($*IN.slurp.AST);
Raku
INFO