I am creating a lezer grammar for the ChordPro format. I am currently working on the Environment Directive.
A start to an environment with label can be described in the following two ways:
{start_of_verse: Verse 1}
// "Verse 1" is an unnamed value which
// symbolized the label of the environment.
// and
{start_of_verse: label=“Verse 1”}
// "label="Verse 1"" is an attribute of
// the environment, where the "name"
// is "label", and "value" is "Verse 1".
I currently have the following grammar working:
environmentStart {
"{"
environmentStartKeyword
directiveSeparator
(EnvironmentLabel | DirectiveAttributes)
"}"
}
// Currently, the label can only consist of
// what `identifier` is and the additional
// rules/tokens i add here. I'll rather like
// a restrictive rule `![...]`.
EnvironmentLabel {
(identifier | labelNumber)
(identifier | labelNumber | " ")*
}
DirectiveAttributes {
DirectiveAttribute (space DirectiveAttribute)*
}
DirectiveAttribute {
DirectiveAttributeName "=" DirectiveAttributeValue
}
DirectiveAttributeName {
identifier
}
DirectiveAttributeValue { string }
@tokens {
space { $[ \t]+ }
identifier {
(@asciiLetter | "_")
(@asciiLetter | @digit | "_")*
}
labelNumber {
@digit+
}
string { "\"" (!["\\] | "\\" _)* "\"" }
}
When using the {start_of_verse: Verse 1} syntax of writing the environment start, basicly all non-functional characters and symbols should be allowed, as } denotes the end of the environment label. Although to make the (EnvironmentLabel | DirectiveAttributes) grammar work, EnvironmentLabel and DirectiveAttributes must share identifier, and then further characters can be allowed for EnvironmentLabel by adding characters/tokens to the rule. I ideally want to use a “anti”-rule instead for EnvironmentLabel, so that i dont have to specify every possible character out there for compatibility. This rule (or something similar) would be ideal:
EnvironmentLabel {
directiveUnnamedLabel
}
@tokens {
directiveUnnamedLabel {
![{}\[\]\r\n\t="':]
![ {}\[\]\r\n\t="':]*
}
}
But this rule gives me an overlapping tokens error between directiveUnnamedLabel and identifier.
So my question is:
- Can i somehow have an “anti”-rule (
![...]) inEnvironmentLabel, and still have(EnvironmentLabel | DirectiveAttributes)working for the two cases{start_of_verse: Verse 1}and{start_of_verse: label="Verse 1"}? How do i make it work then? - Or do i need to keep the “positive”-rule and specify every character that i want to allow in the
EnvironmentLabelrule?