The Any And Complement Operators

As a result of popular demand, the Any operator has been implemented. Yet, it has been decided not to implement a Complement operator. Explanations follow.

Complement

The Complement is usually known as the '!' operator in POSIX syntax.

This operator is troublesome. On first sight, it would seem obvious that:

  Complement(Any - (10..20)) == Any - (Any - (10..20)) == 10..20

But, if you think about it, all SableCC lexer operators work on regular expressions. So, wouldn't the following make sense, instead?

  Complement('Etienne') == Any* - 'Etienne'

So, what does Complement(X) mean? Is it (Any - X) or (Any* - X)?

It is thus best not to provide this operator. Actually, if you count characters, you'll notice that (Any* - X) is more concise than Complement(X).

(Any - X)     // character set complement
(Any* - X)    // regular expression complement
Complement(X) // ambiguous complement

It is not desirable, either, to introduce the shorter '!' left unary operator. Figuring out the precedence rules between left and right unary operators is not something easy for many developers. Example:

    !('a'..'z')*

Is this equivalent to ( !('a'..'z') )* or to !( ('a'..'z')* ) ? Note that these two regular expressions are not equivalent!

Any

Warning: The following text is highly technical. It was meant for SableCC developers.

The Any operator is better known as the '.' operator in POSIX syntax.

The key idea, to stick as much as possible to the original design of the alphabet package, is to allow for a special symbol in an alphabet that represents all the T elements not covered by the other symbols of the alphabet. This special symbol does not have a list of intervals.

When merging alphabets, null in a symbol pair represents the special symbol.

See the javadoc documentation and comments within the source code for details.