/// <summary>
        /// Creates a parser for identifier-start-character
        /// </summary>
        /// <returns></returns>
        public static IParser <char, char> IdentifierStartCharacter()
        {
            // identifier-start-character:
            //   letter-character
            //   _ (the underscore character U+005F)
            // letter-character:
            //   A Unicode character of classes Lu, Ll, Lt, Lm, Lo, or Nl
            //   A unicode-escape-sequence representing a character of classes Lu, Ll, Lt, Lm, Lo, or Nl
            return(Expect.Char(symbol =>
            {
                if (symbol == '_')
                {
                    return true;
                }
                switch (CharUnicodeInfo.GetUnicodeCategory(symbol))
                {
                case UnicodeCategory.UppercaseLetter: //Lu
                case UnicodeCategory.LowercaseLetter: //Ll
                case UnicodeCategory.TitlecaseLetter: //Lt
                case UnicodeCategory.ModifierLetter:  //Lm
                case UnicodeCategory.OtherLetter:     //Lo
                case UnicodeCategory.LetterNumber:    //Nl
                    return true;

                default:
                    return false;
                }
            }));
        }
 /// <summary>
 /// Creates a parser for an identifier
 /// </summary>
 /// <returns>the parser</returns>
 public static IParser <char, string> Identifier()
 {
     // identifier:
     //   available-identifier
     //   @ identifier-or-keyword
     return(Expect.OneOf(
                AvailableIdentifier(),
                Expect.Concatenation(
                    Expect.Char('@'),
                    IdentifierOrKeyWord(),
                    (at, identifierOrKeyWord) => string.Concat(at, identifierOrKeyWord))
                ));
 }
        /// <summary>
        /// Creates a Parser for identifier-part-character
        /// </summary>
        /// <returns></returns>
        public static IParser <char, char> IdentifierPartCharacter()
        {
            // identifier-part-character:
            //   letter-character
            //   decimal-digit-character
            //   connecting-character
            //   combining-character
            //   formatting-character
            // letter-character:
            //   A Unicode character of classes Lu, Ll, Lt, Lm, Lo, or Nl
            //   A unicode-escape-sequence representing a character of classes Lu, Ll, Lt, Lm, Lo, or Nl
            // combining-character:
            //   A Unicode character of classes Mn or Mc
            //   A unicode-escape-sequence representing a character of classes Mn or Mc
            // decimal-digit-character:
            //   A Unicode character of the class Nd
            //   A unicode-escape-sequence representing a character of the class Nd
            // connecting-character:
            //   A Unicode character of the class Pc
            //   A unicode-escape-sequence representing a character of the class Pc
            // formatting-character:
            //   A Unicode character of the class Cf
            //   A unicode-escape-sequence representing a character of the class Cf
            return(Expect.Char(symbol =>
            {
                switch (CharUnicodeInfo.GetUnicodeCategory(symbol))
                {
                case UnicodeCategory.UppercaseLetter:      //Lu
                case UnicodeCategory.LowercaseLetter:      //Ll
                case UnicodeCategory.TitlecaseLetter:      //Lt
                case UnicodeCategory.ModifierLetter:       //Lm
                case UnicodeCategory.OtherLetter:          //Lo
                case UnicodeCategory.LetterNumber:         //Nl
                case UnicodeCategory.NonSpacingMark:       //Mn
                case UnicodeCategory.SpacingCombiningMark: //Mc
                case UnicodeCategory.DecimalDigitNumber:   //Nd
                case UnicodeCategory.ConnectorPunctuation: //Pc
                case UnicodeCategory.Format:               //Cf
                    return true;

                default:
                    return false;
                }
            }));
        }