CleanAST

Run Settings
LanguageRaku
Language Version
Run Command
my \example-code = "(a + b)*3"; use lib '.'; use ExampleGrammar; use CleanAST :Parens; my \cst = ExampleGrammar .parse: example-code, actions => CleanAST; say .ast given cst
use CleanAST :Parens; unit grammar ExampleGrammar does Parens; rule TOP { <INFIX-EXPR> | <EXPR> } rule INFIX-EXPR { <EXPR> <INFIX> <EXPR> } rule EXPR { <.lparen> <TOP> <.rparen> | <VAL> } token INFIX { <ADD> | <MUL> } token ADD { '+' } token MUL { '*' } token VAL { <IDENT> | <NUM> } token IDENT { <.ident> } token NUM { <.digit>+ }
unit class CleanAST; our $*Parens is export(:Parens); role Parens is Grammar is export(:Parens) { token lparen { '(' {$*Parens++} } token rparen { ')' {$*Parens--} } } # Example of a helper method: sub ast-from-first-child { CALLERS::('$/').caps[0].value.ast } method TOP ($/) { # These two lines could be replaced by a call to the above helper method: with $<INFIX-EXPR> { make $<INFIX-EXPR>.ast } with $<EXPR> { make $<EXPR>.ast } } method EXPR ($/) { # Example of using the above helper method: make ast-from-first-child; # Instead of these two lines: # with $<VAL> { make $<VAL>.ast } # with $<TOP> { make $<TOP>.ast } } method INFIX ($/) { # These two lines could be replaced by a call to a helper routine for ast # nodes which are just strings corresponding to their grammar rule name: with $<ADD> { make 'ADD' } with $<MUL> { make 'MUL' } } method VAL ($/) { # These two lines could be replaced by a call to a helper routine for ast # nodes which are strings constructed based on their grammar rule name: with $<IDENT> { make q:s [IDENT{ str:"$<IDENT>" }] } with $<NUM> { make q:s [NUM{ num:"$<NUM>" }] } } method INFIX-EXPR ($/) { # This code could be replaced by a call to a helper routine that handles the # desired ast formatting for an infix expression. Obviously there could be # helper routines for other typical grammatical slots (prefix, postfix, etc.) my $infix-and-curly = q:s:to<END>.chop; $<INFIX>.ast() { left: $<EXPR>[0].ast(), right: $<EXPR>[1].ast() } END # If indent level above zero, expand indent as appropriate if try $*Parens { $infix-and-curly.=subst: :g, / ^^ ' ' /, ' ' x $*Parens+1; $infix-and-curly.=subst: / ^^ <?before '}'> /, ' ' x $*Parens; } make $infix-and-curly; }
Editor Settings
Theme
Key bindings
Full width
Lines