On 23/11/2005, at 14:26, Sylvain Benilan wrote:
My question is about a language description design. I tried (but failed) to design the grammar such anything that is a valid CLAIRE construct is described by a specific pattern and anything else falls into the scope of 'invalid.illegal.something'. For instance, in CLAIRE, a variable scope is introduced with a 'let' construct :
let x := 1, y := 2 in (x + y) // valid let x := 1, y := 2 *BAD* in (x + y) // invalid : *BAD* illegal
The rule that describe the 'let' construct would look like :
let <#var-def-list> in <#any>
Which can't be described with a begin/end pattern, unless I can reference a repository rule from whitin the begin/end pattern. Can we do that ?
It is possible to include a repository rule as one of the sub-rules inside begin/end. But what you want to do is not straightforward. The Property List (Old-Style) does rather strict matching, e.g. it'll allow: ( foo, bar ) as an array, but not: ( foo bar ) or ( foo, , bar ).
The way this is done is by matching everything that is valid in the current context, and then have a catch-all rule last, which matches the leftovers as invalid.
So for example for the let … in part, we could make a rule like this:
begin = "\blet\b"; end = "\bin\b"; patterns = ( { include = "#variable-declaration"; }, // should match optional trailing comma { match = "\S"; name = "invalid.illegal...."; } // we should never reach this! );
(\S is everything but whitespace)
To be really strict though, this can quickly get rather complex. Also keep in mind, that often syntax highlight lose a bit of value, if it doesn't color anything until the complete statement is correct, so being 100% strict is not always an advantage.