private void ExtendIdentifierCharacterRanges(CharacterSet identifierCharSet)
        {
            var characterRanges = ListAllCharacterRanges();

            foreach (var charRange in characterRanges)
            {
                identifierCharSet.AddCharacters(charRange.ToCharacterSet());
            }
        }
Exemplo n.º 2
0
        // Content text is an unusual parse rule compared with most since it's
        // less about saying "this is is the small selection of stuff that we parse"
        // and more "we parse ANYTHING except this small selection of stuff".
        protected string ContentTextNoEscape()
        {
            // Eat through text, pausing at the following characters, and
            // attempt to parse the nonTextRule.
            // "-": possible start of divert or start of gather
            // "<": possible start of glue
            if (_nonTextPauseCharacters == null)
            {
                _nonTextPauseCharacters = new CharacterSet("-<");
            }

            // If we hit any of these characters, we stop *immediately* without bothering to even check the nonTextRule
            // "{" for start of logic
            // "|" for mid logic branch
            if (_nonTextEndCharacters == null)
            {
                _nonTextEndCharacters       = new CharacterSet("{}|\n\r\\");
                _notTextEndCharactersChoice = new CharacterSet(_nonTextEndCharacters);
                _notTextEndCharactersChoice.AddCharacters("[]");
                _notTextEndCharactersString = new CharacterSet(_nonTextEndCharacters);
                _notTextEndCharactersString.AddCharacters("\"");
            }

            // When the ParseUntil pauses, check these rules in case they evaluate successfully
            ParseRule nonTextRule = () => OneOf(ParseDivertArrow, EndOfLine, Glue);

            CharacterSet endChars = null;

            if (parsingStringExpression)
            {
                endChars = _notTextEndCharactersString;
            }
            else if (_parsingChoice)
            {
                endChars = _notTextEndCharactersChoice;
            }
            else
            {
                endChars = _nonTextEndCharacters;
            }

            string pureTextContent = ParseUntil(nonTextRule, _nonTextPauseCharacters, endChars);

            if (pureTextContent != null)
            {
                return(pureTextContent);
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 3
0
        public string ParseCharactersFromCharSet(CharacterSet charSet, bool shouldIncludeChars = true, int maxCount = -1)
        {
            if (maxCount == -1)
            {
                maxCount = int.MaxValue;
            }

            int startIndex = index;

            // Optimisation from profiling:
            // Store in temporary local variables
            // since they're properties that would have to access
            // the rule stack every time otherwise.
            int i   = index;
            int cli = characterInLineIndex;
            int li  = lineIndex;

            int count = 0;

            while (i < _chars.Length && charSet.Contains(_chars [i]) == shouldIncludeChars && count < maxCount)
            {
                if (_chars [i] == '\n')
                {
                    li++;
                    cli = -1;
                }
                i++;
                cli++;
                count++;
            }

            index = i;
            characterInLineIndex = cli;
            lineIndex            = li;

            int lastCharIndex = index;

            if (lastCharIndex > startIndex)
            {
                return(new string (_chars, startIndex, index - startIndex));
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 4
0
        // Note: we allow identifiers that start with a number,
        // but not if they *only* comprise numbers
        protected string Identifier()
        {
            if (_identifierCharSet == null)
            {
                (_identifierCharSet = new CharacterSet())
                .AddRange('A', 'Z')
                .AddRange('a', 'z')
                .AddRange('0', '9')
                .Add('_');
                // Enable non-ASCII characters for story identifiers.
                ExtendIdentifierCharacterRanges(_identifierCharSet);
            }

            // Parse remaining characters (if any)
            var name = ParseCharactersFromCharSet(_identifierCharSet);

            if (name == null)
            {
                return(null);
            }

            // Reject if it's just a number
            bool isNumberCharsOnly = true;

            foreach (var c in name)
            {
                if (!(c >= '0' && c <= '9'))
                {
                    isNumberCharsOnly = false;
                    break;
                }
            }
            if (isNumberCharsOnly)
            {
                return(null);
            }

            return(name);
        }
Exemplo n.º 5
0
        protected object SequenceTypeSymbolAnnotation()
        {
            if (_sequenceTypeSymbols == null)
            {
                _sequenceTypeSymbols = new CharacterSet("!&~$ ");
            }

            var sequenceType        = (SequenceType)0;
            var sequenceAnnotations = ParseCharactersFromCharSet(_sequenceTypeSymbols);

            if (sequenceAnnotations == null)
            {
                return(null);
            }

            foreach (char symbolChar in sequenceAnnotations)
            {
                switch (symbolChar)
                {
                case '!': sequenceType |= SequenceType.Once; break;

                case '&': sequenceType |= SequenceType.Cycle; break;

                case '~': sequenceType |= SequenceType.Shuffle; break;

                case '$': sequenceType |= SequenceType.Stopping; break;
                }
            }

            if (sequenceType == (SequenceType)0)
            {
                return(null);
            }

            return(sequenceType);
        }
Exemplo n.º 6
0
        public string ParseUntil(ParseRule stopRule, CharacterSet pauseCharacters = null, CharacterSet endCharacters = null)
        {
            int ruleId = BeginRule();


            CharacterSet pauseAndEnd = new CharacterSet();

            if (pauseCharacters != null)
            {
                pauseAndEnd.UnionWith(pauseCharacters);
            }
            if (endCharacters != null)
            {
                pauseAndEnd.UnionWith(endCharacters);
            }

            StringBuilder parsedString      = new StringBuilder();
            object        ruleResultAtPause = null;

            // Keep attempting to parse strings up to the pause (and end) points.
            //  - At each of the pause points, attempt to parse according to the rule
            //  - When the end point is reached (or EOF), we're done
            do
            {
                // TODO: Perhaps if no pause or end characters are passed, we should check *every* character for stopRule?
                string partialParsedString = ParseUntilCharactersFromCharSet(pauseAndEnd);
                if (partialParsedString != null)
                {
                    parsedString.Append(partialParsedString);
                }

                // Attempt to run the parse rule at this pause point
                ruleResultAtPause = Peek(stopRule);

                // Rule completed - we're done
                if (ruleResultAtPause != null)
                {
                    break;
                }
                else
                {
                    if (endOfInput)
                    {
                        break;
                    }

                    // Reached a pause point, but rule failed. Step past and continue parsing string
                    char pauseCharacter = currentCharacter;
                    if (pauseCharacters != null && pauseCharacters.Contains(pauseCharacter))
                    {
                        parsedString.Append(pauseCharacter);
                        if (pauseCharacter == '\n')
                        {
                            lineIndex++;
                        }
                        index++;
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
            } while(true);

            if (parsedString.Length > 0)
            {
                return((string)SucceedRule(ruleId, parsedString.ToString()));
            }
            else
            {
                return((string)FailRule(ruleId));
            }
        }
Exemplo n.º 7
0
 public string ParseUntilCharactersFromCharSet(CharacterSet charSet, int maxCount = -1)
 {
     return(ParseCharactersFromCharSet(charSet, false, maxCount));
 }
Exemplo n.º 8
0
 public CharacterSet(CharacterSet charSetToCopy)
 {
     AddCharacters(charSetToCopy);
 }