Coco ::=
	// using statements
	ANY*
	"COMPILER" ident
	ANY*
	"IGNORECASE"?   /* pdt */
	( "CHARACTERS"  SetDecl*)?
	( "TOKENS"  TokenDecl*)?
	( "PRAGMAS" TokenDecl*)?
	( "COMMENTS" "FROM" TokenExpr "TO" TokenExpr "NESTED"?)*
	( "IGNORE" Set )*
	SYNC
	"PRODUCTIONS"
	( ident AttrDecl? SemText? WEAK '=' Expression  WEAK '.' )*
	"END" ident  '.'

/*------------------------------------------------------------------------------------*/

SetDecl ::= ident '=' Set '.'

/*------------------------------------------------------------------------------------*/

Set ::= SimSet ( '+' SimSet  | '-' SimSet )*

/*------------------------------------------------------------------------------------*/

SimSet   ::= ident
           | string
           | Char ( '..' Char )?
           | 'ANY'

/*--------------------------------------------------------------------------------------*/

Char ::= char

/*------------------------------------------------------------------------------------*/

TokenDecl ::= Sym SYNC ( '=' TokenExpr '.'  )? SemText?

/*------------------------------------------------------------------------------------*/

AttrDecl ::= '<' ( ANY | badString )* '>'
           | '<.' ( ANY | badString )* '.>'

/*------------------------------------------------------------------------------------*/

Expression ::= Term ( WEAK '|' Term )*

/*------------------------------------------------------------------------------------*/

Term ::= Resolver? Factor+

/*------------------------------------------------------------------------------------*/

Factor   ::= 'WEAK'? Sym Attribs?
           | '(' Expression ')'
           | '[' Expression ']'
           | '{' Expression '}'
           | SemText
           | 'ANY'
           | 'SYNC'

/*------------------------------------------------------------------------------------*/

Resolver ::= "IF" "("  Condition

/*------------------------------------------------------------------------------------*/

Condition ::= ( "(" Condition | ANY )* ")"

/*------------------------------------------------------------------------------------*/

TokenExpr ::= TokenTerm ( WEAK '|' TokenTerm )*

/*------------------------------------------------------------------------------------*/

TokenTerm ::= TokenFactor+ ( 'CONTEXT' '(' TokenExpr ')' )?

/*------------------------------------------------------------------------------------*/

TokenFactor ::= Sym
           | '(' TokenExpr ')'
           | '[' TokenExpr ']'
           | '{' TokenExpr '}'

/*------------------------------------------------------------------------------------*/

Sym      ::= ident
           | string
           | char

/*------------------------------------------------------------------------------------*/

Attribs  ::= '<' ( ANY | badString )* '>'
           | '<.' ( ANY | badString )* '.>'

/*------------------------------------------------------------------------------------*/

SemText ::= "(." ( ANY | badString | "(." )* ".)"

/* ---- TOKENS ----- */

ident     ::= letter ( letter | digit )*
number    ::= digit+
string    ::= '"' ( stringCh | '\' printable )* '"'
badString ::= '"' ( stringCh | '\' printable )* (cr | lf)
char      ::= "'" ( charCh | '\' printable hex* ) "'"

/* ---- CHARACTERS ----- */
letter    ::= [A-Za-z_]
digit     ::= [0-9]
cr        ::= #xD
lf        ::= #xA
tab       ::= #x9
stringCh  ::= [^"\#xD#xA] //ANY - '"' - '\\' - cr - lf
charCh    ::= [^'\#xD#xA] //ANY - '\'' - '\\' - cr - lf
printable ::=  [#x0020-#x007e]
hex       ::= (digit | [a-f])+