I have written this - it works fine:
use Grammar::Tracer;
my grammar Lambda {
token TOP { <signature> <body> ' as ' <r-type> }
rule signature { '|' <a-sig> [',' <b-sig>]? '|' }
rule a-sig { 'a:' <a-type> }
rule b-sig { 'b:' <b-type> }
token body { '(' <expr> ')' <?before ' as '> }
token expr { <-[()]>* }
token a-type { @types }
token b-type { @types }
token r-type { @types }
}
Lambda.parse("|a: i32, b: i32| (a + b) as i32");
gives what I need:
TOP
| signature
| | a-sig
| | | a-type
| | | * MATCH "i32"
| | * MATCH "a: i32"
| | b-sig
| | | b-type
| | | * MATCH "i32"
| | * MATCH "b: i32"
| * MATCH "|a: i32, b: i32| "
| body
| | expr
| | * MATCH "a + b"
| * MATCH "(a + b)"
| r-type
| * MATCH "i32"
* MATCH "|a: i32, b: i32| (a + b) as i32"
BUT I would like to do this string (and similar):
|a: str, b: i32| (a.len() as i32 + b) as i32
- this fails since it exit the body match on the len() parens
- even when I fix that it exits on the first as i32
I would like to find some way to "pin" the match to be the last valid match for 'as type' before the end of the string
And how to match but not capture only the other parens.
please
'(' ~ ')' <expr>
for example? See discussion here: docs.raku.org/language/regexes#Tilde_for_nesting_structures . I can write this up as a full answer if useful. β Offshore