Consider the following which declares an enum grammar that wants to enforce a minimum requirement on the number of members. This works,
Enums <- Enum*
%whitespace <- [ \t\r\n]*
%word <- [A-Za-z0-9_.]+
NAME <- < [A-Za-z_][A-Za-z0-9_]* >
Enum <- 'enum' ↑ $name<NAME> '{' ↑ NAME+^enum_count '}'
enum_count <- '' { error_message "enum must contain at least one member" }
but it is inelegant:
It would be really nice if we could use the named capture in error_message. Some thoughts:
You could change the grammar to make allow error_message BACKREFERENCE (',' BACKREFERENCE) string_literal which would print the backreferences with a ': " after each one.
meh.
You could allow sprintf or std::format formatting, error_message "{}: must have at least one member", $name,
You could perhaps provide an automatic "context stack". Consider, to which captures are automatically pushed/popped using '$^' instead of just '$', and $^'...' to push a literal:
TypeDef <- $^type<'type'> ↑ $^name<NAME> Parent? '{' Members '}'
Members <- Member (',' Member)* ','?
Member <- $^'member' $type<NAME> $^field<NAME> MemberDefault
MemberDefault <- '{' '}' # imagine there's some complex recursion here
Or perhaps rather than the ugly '$^'member' you could allow '^' infront of the production name to indicate it should push its name onto the context stack:
^Type <- 'type' ↑ $^name<NAME> Parent? '{' Members '}'
Members <- Member (',' Member)* ','?
^Member <- $type<NAME> $^field<NAME> DefaultValue
^DefaultValue <- '{' '}'
Consider the following which declares an enum grammar that wants to enforce a minimum requirement on the number of members. This works,
but it is inelegant:
It would be really nice if we could use the named capture in error_message. Some thoughts:
You could change the grammar to make allow
error_message BACKREFERENCE (',' BACKREFERENCE) string_literal
which would print the backreferences with a ': " after each one. meh.You could allow sprintf or std::format formatting,
error_message "{}: must have at least one member", $name
,You could perhaps provide an automatic "context stack". Consider, to which captures are automatically pushed/popped using '$^' instead of just '$', and $^'...' to push a literal:
Now this has the capability automatically take:
and report
Or perhaps rather than the ugly '$^'member' you could allow '^' infront of the production name to indicate it should push its name onto the context stack:
If we tighten this down to one $^ per production, you can design the format so that, in rust terms: