예제 #1
0
        public Tree Parse(Token[] tokens)
        {
            var tree = new Tree();

            tokens = PreProcessor.FilterComments(tokens);

            if(tokens == null || tokens.Length == 0)
            {
                tree.Errors.Add(CreateError(null, ErrorStrings.NoRulesFound));
                return tree;
            }
            
            for(var i = 0; i < tokens.Length; i++)
            {
                var token = tokens[i];
                
                if(token is Identifier)
                {
                    ParseRule(tree, token, tokens, ref i);
                }
            }

            if(tree.Rules.Count == 0)
            {
                tree.Errors.Add(CreateError(null, ErrorStrings.NoRulesFound));
            }

            return tree;
        }
예제 #2
0
        private static void ParseRule(Tree tree, Token token, Token[] tokens, ref int index)
        {
            if (token is Identifier)
            {
                var ruleToken = token;

                var rule = new Rule { Identifier = token.Value };

                token = NextToken(tokens, ref index);

                if (IsDefinition(token))
                {
                    token = NextToken(tokens, ref index);

                    rule.Expression = ParseExpression(tree, ref token, tokens, ref index, ';');

                    tree.Add(rule);
                }
                else
                {
                    ruleToken.Position += 2;
                    tree.Errors.Add(CreateError(ruleToken, string.Format(ErrorStrings.ExpectedDefinition, token == null ? "nothing" : token.Value)));
                }
            }
            else
            {
                tree.Errors.Add(CreateError(token, ErrorStrings.RulesMustBeginWithIdentifier));
            }
        }
예제 #3
0
 private static Token[] RemoveRange(Token[] array, int index, int count)
 {
     // TODO no LINQ
     var list = array.ToList();
     list.RemoveRange(index, count);
     array = list.ToArray();
     return array;
 }
예제 #4
0
        public static Token[] FilterComments(Token[] tokens)
        {
            var before = tokens.Length;
            for (var i = 0; i < tokens.Length; i++)
            {
                var token = tokens[i];
                var last = (tokens.Length - 1 <= i);

                if (!(token is Operator) || !token.Value.Equals("(") || last)
                {
                    continue;
                }

                var next = tokens[i + 1];
                if (!(next is Operator) || !next.Value.Equals("*"))
                {
                    continue;
                }

                var start = i;
                var count = 2;
                NextToken(tokens, ref i);

                token = NextToken(tokens, ref i);
                while (token != null &&
                       !(token.Value.Equals("*") && PeekNextToken(tokens, i) != null &&
                         PeekNextToken(tokens, i).Value.Equals(")")))
                {
                    count++;
                    token = NextToken(tokens, ref i);
                }

                if (token != null)
                {
                    count += 2;
                }

                tokens = RemoveRange(tokens, start, count);
            }
            var after = tokens.Length;
            
            if(after < before)
            {
                tokens = FilterComments(tokens);
            }

            return tokens;
        }
예제 #5
0
 private Tree ParseStream(Stream stream, out Token[] tokens)
 {
     using (stream)
     {
         tokens = _lexer.Scan(stream);
         var tree =_parser.Parse(tokens);
         return tree;
     }
 }
예제 #6
0
 private static Expression ParseExpression(Tree tree, ref Token token, Token[] tokens, ref int index, char terminator)
 {
     var node = new Expression();
     
     while(ParseTerms(node, tree, ref token, tokens, ref index, terminator)) { }
     
     return node;
 }
예제 #7
0
 private static bool IsDefinition(Token token)
 {
     return token != null && (token is Operator) && token.Value.Equals("=");
 }
예제 #8
0
 private static Error CreateError(Token token, string description)
 {
     return new Error { Description = description, Line = token != null ? token.Line : -1, Position = token != null ? token.Position : -1 };
 }
예제 #9
0
 private static Factor ParseFactor(Tree tree, Token token, Token[] tokens, ref int index)
 {
     if(token is Identifier)
     {
         var node = new ebnf.Nodes.Identifier {Value = token.Value};
         return node;
     }
     if(token is Literal)
     {
         var node = new Terminal { Value = token.Value };
         return node;
     }
     if(token is Operator && token.Value.Equals("("))
     {
         token = NextToken(tokens, ref index);
         var node = new Grouping
         {
             Expression = ParseExpression(tree, ref token, tokens, ref index, ')')
         };
         if(!(token is Operator) || !token.Value.Equals(")"))
         {
             tree.Errors.Add(CreateError(token, ErrorStrings.HangingGrouping));
         }
         return node;
     }
     if (token is Operator && token.Value.Equals("["))
     {
         token = NextToken(tokens, ref index);
         var node = new Option
         {
             Expression = ParseExpression(tree, ref token, tokens, ref index, ']')
         };
         if (!(token is Operator) || !token.Value.Equals("]"))
         {
             tree.Errors.Add(CreateError(token, ErrorStrings.HangingOption));
         }
         return node;
     }
     if (token is Operator && token.Value.Equals("{"))
     {
         token = NextToken(tokens, ref index);
         var node = new Repetition
         {
             Expression = ParseExpression(tree, ref token, tokens, ref index, '}')
         };
         if (!(token is Operator) || !token.Value.Equals("}"))
         {
             tree.Errors.Add(CreateError(token, ErrorStrings.HangingRepetition));
         }
         return node;
     }
     if (token is Operator && token.Value.Equals("?"))
     {
         token = NextToken(tokens, ref index);
         var node = new SpecialSequence
         {
             Expression = ParseExpression(tree, ref token, tokens, ref index, '?')
         };
         if (!(token is Operator) || !token.Value.Equals("?"))
         {
             tree.Errors.Add(CreateError(token, ErrorStrings.HangingSpecialSequence));
         }
         return node;
     }
     tree.Errors.Add(CreateError(token, string.Format(ErrorStrings.ExpectedFactor, token == null ? "nothing" : token.Value)));
     return null;
 }
예제 #10
0
        private static Term ParseTerm(Tree tree, ref Token token, Token[] tokens, ref int index)
        {
            var node = new Term();

            var first = ParseFactor(tree, token, tokens, ref index);

            if(first != null)
            {
                node.Factors.Add(first);
            }

            token = NextToken(tokens, ref index);

            if (token == null)
            {
                return node;
            }

            while (token is Literal || !EqualsAny(token.Value, new[] 
            {
                '-', // Except
                '*', // Repetition 
                ',', // Concatentation
                ';', // Termination
                '=', // Definition
                '|', // Alternation
                ')', // End Grouping
                ']', // End Option
                '}', // End Repetition
                '?'  // Special Sequence
            }))
            {
                var additional = ParseFactor(tree, token, tokens, ref index);

                if (additional != null)
                {
                    node.Factors.Add(additional);
                }

                token = NextToken(tokens, ref index);

                if(token == null)
                {
                    return node;
                }
            }

            return node;
        }
예제 #11
0
 private static bool IsRepeat(Token token)
 {
     return token is Operator && token.Value.Equals("*");
 }
예제 #12
0
 private static bool IsConcatenation(Token token)
 {
     return token is Operator && token.Value.Equals(",");
 }
예제 #13
0
 private static bool IsAlternation(Token token)
 {
     return token is Operator && token.Value.Equals("|");
 }
예제 #14
0
 private static bool IsExcept(Token token)
 {
     return token is Operator && token.Value.Equals("-");
 }
예제 #15
0
 private static bool IsExpressionOperator(Token token)
 {
     return token is Operator && (token.Value.Equals("|") || token.Value.Equals(",") || token.Value.Equals("*") || token.Value.Equals("-"));
 }
예제 #16
0
        private static bool ParseTerms(Expression node, Tree tree, ref Token token, Token[] tokens, ref int index, char terminator)
        {
            var term = ParseTerm(tree, ref token, tokens, ref index);

            node.Terms.Add(term);

            if (token == null || token is Operator && token.Value.Equals(terminator.ToString(CultureInfo.InvariantCulture)))
            {
                return false;
            }

            while (IsExpressionOperator(token))
            {
                if (IsAlternation(token))
                {
                    node.Operators.Add(new Alternation { Value = token.Value });
                }
                if (IsConcatenation(token))
                {
                    node.Operators.Add(new Concatenation { Value = token.Value });
                }
                if (IsRepeat(token))
                {
                    node.Operators.Add(new Repeat { Value = token.Value });
                }
                if (IsExcept(token))
                {
                    node.Operators.Add(new Except { Value = token.Value });
                }
                token = NextToken(tokens, ref index);
            }

            return true;
        }