public List<TokenMatch> Parse(string grammar)
        {
            // $month:@starttoken.value $day:@number $dayend:( st | nd | rd | th )? ( ','?  $year:@number )?"
            _pos = 0;
            _grammar = grammar;
            _errors = new List<string>();
            END = _grammar.Length;
            _matches = new List<TokenMatch>();
            while (_pos < END)
            {
                var c = _grammar[_pos];

                // Case 1: Begin a token match.
                if (c == '$' || c == '\'')
                {
                    var match = ReadToken();
                    AddMatch(match);
                }
                // Case 2: Move past white space.
                else if (c == '\t' || c == ' ')
                {
                    _pos++;
                }
                // Case 3: Last token was optional
                else if (c == '?')
                {
                    _pos++;
                    var last = this.Last();
                    if(_groupCount > 0 && last.IsGroup)
                    {
                        var group = ((TokenGroup) last);
                        last = group.Matches[group.Matches.Count - 1];
                    }
                    last.IsRequired = false;
                }
                // Case 4: "(" starts a grouping of token matches
                else if( c == '(')
                {
                    _pos++;
                    this.BeginGroup();
                }
                else if (c == ')')
                {
                    _pos++;
                    CloseGroup();
                }
                // Case 5: word
                else if (char.IsLetter(c))
                {
                    var word = ReadWord();
                    var match = new TokenMatch();
                    match.Text = word;
                    match.IsRequired = true;
                    AddMatch(match);
                }
                else
                    _pos++;
            }
            return _matches;
        }
 private void AddMatch(TokenMatch match)
 {
     var last = Last();
     if(_groupCount > 0 && last != null && last.IsGroup)
     {
         ((TokenGroup) last).Matches.Add(match);
     }
     else
     {
         _matches.Add(match);
     }
 }
        /// <summary>
        /// Reads a token value : usually after ":" and includes type e.g. @number @bool
        /// </summary>
        /// <param name="match"></param>
        private void ReadTokenValue(TokenMatch match)
        {
            var c = _grammar[_pos];
            if (c == '@')
            {
                _pos++;
                var tokenType = ReadWord();
                match.TokenType = "@" + tokenType;

                if (_pos < END)
                {
                    // Check for ".value"
                    c = _grammar[_pos];
                    if (c == '.')
                    {
                        _pos++;
                        var val = ReadWord();
                        if (val == "value")
                        {
                            match.TokenPropEnabled = true;
                            match.TokenPropValue = val;
                        }
                    }
                }
            }
            else if (c == '(')
            {
                _pos++;
                var words = ReadList();
                match.Values = words;
            }
            else if (c == ':')
            {
                _pos++;
                match.Text = ":";
            }
        }
        /// <summary>
        /// Reads a token e.g. usually begins with "$"
        /// </summary>
        /// <returns></returns>
        private TokenMatch ReadToken()
        {
            var start = _pos;
            var match = new TokenMatch();
            match.IsRequired = true;

            while (_pos < END)
            {
                var c = _grammar[_pos];
                // Case 1: Begin a token match.
                if (c == '$')
                {
                    _pos++;
                    var word = ReadWord();
                    match.Name = word;

                    // Expect ":" followed by tokenvalue
                    this.Expect(':');
                    this.ReadTokenValue(match);
                    break;
                }
                // Case 2: Move past white space.
                else if (c == '\t' || c == ' ')
                {
                    _pos++;
                }
                else if ( c == '\'')
                {
                    _pos++;
                    match.Text = ReadString();
                    break;
                }
                else
                    break;
            }
            return match;
        }
 public void AddMatch(TokenMatch m)
 {
     this.Matches.Add(m);
 }
Exemple #6
0
        private void DoParse()
        {
            while (_pos < END)
            {
                var c = _grammar[_pos];

                // Case 1: Begin a token match.
                if (c == '$' || c == '\'')
                {
                    var match = ReadToken();
                    AddMatch(match);
                }
                // Case 2: '@' specific type of word/identifier
                else if (c == '@')
                {
                    _pos++;
                    var tokenType = ReadWord();
                    var match     = new TokenMatch();
                    match.TokenType  = "@" + tokenType;
                    match.IsRequired = true;
                    AddMatch(match);
                }
                // Case 3: Move past white space.
                else if (c == '\t' || c == ' ')
                {
                    _pos++;
                }
                // Case 4: Last token was optional
                else if (c == '?')
                {
                    _pos++;
                    var last = Last();
                    if (_groupCount > 0 && last.IsGroup)
                    {
                        var group = ((TokenGroup)last);
                        last = group.Matches[group.Matches.Count - 1];
                    }
                    last.IsRequired = false;
                }
                // Case 5: "(" starts a grouping of token matches
                else if (c == '(')
                {
                    _pos++;
                    BeginGroup();
                }
                else if (c == ')')
                {
                    _pos++;
                    CloseGroup();
                }
                // Case 6: word
                else if (char.IsLetter(c))
                {
                    var word  = ReadWord();
                    var match = new TokenMatch();
                    match.Text       = word;
                    match.IsRequired = true;
                    AddMatch(match);
                }
                // Case 7: |
                else if (c == '|')
                {
                    _orCount++;
                    _operatorStack.Add("|");
                    _pos++;
                }
                // Case 8: escape \
                else if (c == '\\')
                {
                    _pos++;
                    var escapedChar = _grammar[_pos];
                    var match       = new TokenMatch();
                    match.Text       = escapedChar.ToString();
                    match.IsRequired = true;
                    AddMatch(match);

                    // Move past escaped char
                    _pos++;
                }
                // Case 9: #reference
                else if (c == '#')
                {
                    var match = ReadToken();
                    match.Ref  = match.Name;
                    match.Name = null;
                    AddMatch(match);
                }
                else
                {
                    _pos++;
                }
            }
        }