示例#1
0
        //public void SetStartRule(NonTerminalToken token)
        //    => startRule = GetRule(token);

        //public void SetStartRule(string tokenName)
        //    => SetStartRule(new NonTerminalToken(tokenName));


        public ParseNode Parse(string input, int lineNum)
        {
            if (startRule == null)
            {
                if (rules.Count == 0)
                {
                    throw new Exception("No start rule found!\n");
                }
                // The first rule is the start rule!
                startRule = rules[0];
            }
            return(Parse(startRule, ref input, 0, lineNum));
        }
示例#2
0
        public void AddRule(BnfRule rule)
        {
            NonTerminalToken lhs = rule.LeftHandSide;

            foreach (BnfRule ruleIn in rules)
            {
                if (lhs.equals(ruleIn.LeftHandSide))
                {
                    ruleIn.AddPossibilities(rule.GetPossibilities());
                    break;
                }
            }
            this.rules.Add(rule); // No rule with the same LHS found
        }
示例#3
0
        public List <BnfRule> GetRules(StreamReader grammar)
        {
            string         line;
            List <BnfRule> rulesList = new List <BnfRule>();

            //if (grammar.ReadLine() == null) //problem
            //  throw new Exception("Invalid Grammar Exception - Grammar is empty!");

            while ((line = grammar.ReadLine()) != null)
            {
                int index;
                // Skipping comments; comment start with '#'
                if ((index = line.IndexOf('#')) != -1)
                {
                    line = line.Substring(0, index);
                }

                // Remove all leading and trailing white-space characters from the current string object
                line = line.Trim();
                if (String.IsNullOrEmpty(line) || line.StartsWith("#"))
                {
                    continue;
                }

                try
                {
                    BnfRule newRule = BnfRule.ParseRule(line);
                    rulesList.Add(newRule);
                }
                catch (Exception e)
                {
                    throw new Exception(string.Format(e.Message + " + Invalid Grammar Exception - line: {0}", line));
                }
            }

            //if (!string.IsNullOrEmpty(lineForError))
            //    throw new Exception("Error parsing rule : " + lineForError);
            return(rulesList);
        }
示例#4
0
        //public static string inputCpy;

        public BnfParser()
        {
            startRule = null;
            rules     = new List <BnfRule>();
        }
示例#5
0
        public ParseNode Parse(BnfRule rule, ref string input, int recursionStep, int lineNum)
        {
            // When the maximum recursion depth is reached program throws exception.
            if (recursionStep > maxRecursionSteps)
            {
                throw new Exception(string.Format("Max. number of recursion steps reached. Error line : {0}", lineNum));
            }

            ParseNode node       = null;
            bool      wrongToken = true;
            string    inputCpy   = "";

            inputCpy += input;
            foreach (TokenList poss in rule.GetPossibilities())
            {
                node       = new ParseNode();
                node.Token = node.Value = rule.LeftHandSide.Name;
                TokenList           newPossib      = poss.getCopy();
                IEnumerator <Token> possibIterator = newPossib.GetEnumerator();
                wrongToken = false;
                inputCpy   = "";
                inputCpy  += input;
                while (possibIterator.MoveNext() && !wrongToken) // checks if it has next token
                {
                    inputCpy = inputCpy.Trim();
                    Token possToken = possibIterator.Current;
                    if (possToken is TerminalToken)
                    {
                        if (string.IsNullOrEmpty(inputCpy))
                        {
                            wrongToken = true;
                            break;
                        }

                        int limit = possToken.match(inputCpy);
                        if (limit > 0)
                        {
                            ParseNode child          = new ParseNode();
                            string    inputSubstring = inputCpy.Substring(0, limit);
                            inputCpy = inputCpy.Remove(0, inputSubstring.Length);

                            if (possToken is RegexTerminalToken)
                            {
                                child = AddRegexToken(child, (RegexTerminalToken)possToken, inputSubstring);
                            }

                            child.Token = inputSubstring;
                            node.AddChild(child);
                        }
                        //else if (limit == -1)
                        //{
                        //    if (possToken is StandardExpressionTerminalToken && !((StandardExpressionTerminalToken)possToken).IsItAMatch(inputCpy))
                        //        throw new Exception("Regex not mached [" + possToken.Name + "] -> " + inputCpy + "\n");

                        //    else if (possToken is BigCityTerminalToken && !((BigCityTerminalToken)possToken).IsItAMatch(inputCpy))
                        //        throw new Exception("City not mached! City: " + inputCpy + "\n");
                        //}
                        else // No match; rule expects token
                        {
                            wrongToken = true;
                            node       = null;
                            break;
                        }
                    }
                    else // Parse non-terminal token
                    {
                        ParseNode child   = null;
                        BnfRule   newRule = GetRule(possToken);
                        if (newRule == null)
                        {
                            throw new Exception("There is rule missing for the non-terminal token '" + possToken.Name + "'!\n");
                        }

                        child = Parse(newRule, ref inputCpy, recursionStep + 1, lineNum);
                        if (child == null) // Parsing failed!
                        {
                            wrongToken = true;
                            node       = null;
                            break;
                        }
                        node.AddChild(child);
                    }
                }
                if (!wrongToken)
                {
                    if (!possibIterator.MoveNext())
                    {
                        if (recursionStep > 0 || (recursionStep == 0 && inputCpy.Trim().Length == 0))
                        {
                            break;
                        }
                    }
                    else
                    {
                        wrongToken = true;
                        inputCpy   = "";
                        inputCpy  += input;
                        break;
                    }
                }
            }
            int consumedLength = input.Length - inputCpy.Length;

            if (wrongToken || consumedLength == 0)
            {
                return(null);
            }

            input = input.Substring(consumedLength);
            if (recursionStep == 0 && !string.IsNullOrEmpty(input))
            {
                return(null);
            }

            return(node);
        }