// CharClass : "[" ["^"] {code | code "-" code | FilteredClass}+ "]" ; internal Leaf CharClass() { // Assert chr == '[' // Need to build a new string taking into account char escapes Leaf leaf = new Leaf( RegOp.charClass ); bool invert = false; scan(); // read past '[' if (!esc && chr == '^') { invert = true; scan(); // read past '^' } leaf.rangeLit = new RangeLiteral( invert ); // Special case of '-' at start, taken as ordinary class member. // This is correct for LEX specification, but is undocumented // behavior for FLEX. GPLEX gives a friendly warning, just in // case this is actually a typographical error. if (!esc && chr == '-') { Warn( 113, index - 1, 1, "-" ); leaf.rangeLit.list.Add( new CharRange( '-' ) ); scan(); // read past -' } while (chr != NUL && (esc || chr != ']')) { int lhCodePoint; int startIx = index - 1; // save starting index for error reporting lhCodePoint = (esc ? EscapedChar() : CodePoint()); if (!esc && lhCodePoint == (int)'-') Error( 82, startIx, index - startIx, null ); // // There are three possible elements here: // * a singleton character // * a character range // * a filtered class like [:IsLetter:] // if (chr == '[' && !esc && peek() == ':') // character category { Leaf rslt = FilteredClass(); leaf.Merge( rslt ); } else { scan(); if (!esc && chr == '-') // character range { scan(); if (!esc && chr == ']') { // Special case of '-' at end, taken as ordinary class member. // This is correct for LEX specification, but is undocumented // behavior for FLEX. GPLEX gives a friendly warning, just in // case this is actually a typographical error. leaf.rangeLit.list.Add( new CharRange( lhCodePoint ) ); leaf.rangeLit.list.Add( new CharRange( '-' ) ); //Error(81, idx, index - idx - 1); Warn( 114, startIx, index - startIx - 1, String.Format( CultureInfo.InvariantCulture, "'{0}','{1}'", CharacterUtilities.Map( lhCodePoint ), '-' ) ); } else { int rhCodePoint = (esc ? EscapedChar() : CodePoint()); if (rhCodePoint < lhCodePoint) Error( 54, startIx, index - startIx, null ); scan(); leaf.rangeLit.list.Add( new CharRange( lhCodePoint, rhCodePoint ) ); } } else // character singleton { leaf.rangeLit.list.Add( new CharRange( lhCodePoint ) ); } } } checkAndScan( ']' ); leaf.rangeLit.list.Canonicalize(); return leaf; }