Пример #1
0
 public ParseNode(ParseToken Token)
 {
     if (Token.type == TokenType.SYMBOL)
     {
         Value = TruthValue.Unknown;
     }
     else
     {
         Value = null;
     }
     this.Token = Token;
     Left       = null;
     Right      = null;
 }
Пример #2
0
        /// <summary>
        /// Given the string of original input, a list of Parse Tokens, and the
        /// target offender, find the index the token begins and the length of the
        /// token.
        /// </summary>
        /// <param name="Input">Original infix input. </param>
        /// <param name="List">Sequence of infix tokens. </param>
        /// <param name="Target">Token to find the start index and length of</param>
        /// <param name="Start">0 based index in Input were Target begins.</param>
        /// <param name="Length">Length of target in characters. </param>
        /// <returns></returns>
        private static bool FindToken(string Input, List <ParseToken> List, ParseToken Target,
                                      out int Start, out int Length)
        {
            int cur_ind = 0;

            foreach (ParseToken pt in List)
            {
                cur_ind = Input.IndexOf(pt.symbol, cur_ind);
                if (pt == Target)
                {
                    break;
                }
            }
            Start  = cur_ind;
            Length = Target.symbol.Length;
            return(true);
        }
Пример #3
0
        /// <summary>
        /// Break down a string of space delmited input into parse tokens. If a token
        /// does not follow syntax, a FormatException will be thrown.
        /// </summary>
        /// <param name="input">Space delimited input</param>
        /// <returns></returns>
        private static List <ParseToken> Tokenize(string input)
        {
            List <ParseToken> result = new List <ParseToken>();

            string[] toks = input.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string t in toks)
            {
                try
                {
                    result.Add(ParseToken.Parse(t));
                }
                catch (ArgumentException)
                {
                    throw new FormatException(string.Format("{0} is not a valid operator or symbol.", t));
                }
            }
            return(result);
        }
Пример #4
0
        /// <summary>
        /// Attempt to parse an RPN sequence of Parse tokens. If successful return the reslting
        /// tree, else return null and populate the Error and ErrorMessage parameters.
        /// </summary>
        /// <param name="Input">RPN sequence of Tokens. </param>
        /// <param name="Error">Container for Token of Error</param>
        /// <param name="ErrorMessage">Error message regarding violating token. </param>
        /// <returns>A binary expression tree if succesful, otherwise null. </returns>
        public static ParseTree Parse(List <ParseToken> Input, out ParseToken Error, out string ErrorMessage)
        {
            Dictionary <string, List <ParseNode> > symbolTable = new Dictionary <string, List <ParseNode> >();
            Stack <ParseNode> wSet = new Stack <ParseNode>(); //Stack for processing.
            ParseNode         c;

            foreach (ParseToken pt in Input)
            {
                try
                {
                    c = new ParseNode(pt);
                    if (c.IsOperator)
                    {
                        //NOT is the only operator that requires
                        //a single operand.
                        if (c.Operation == Operation.NOT)
                        {
                            c.Left = wSet.Pop();
                        }
                        else
                        {
                            //Right was placed on the stack last
                            //This order does not matter except for IF operators
                            c.Right = wSet.Pop();
                            c.Left  = wSet.Pop();
                        }
                        //and push it on the stack (fall through)
                    }
                    else
                    {
                        //if its an operand we want to add it to our symbol table.
                        try
                        {
                            symbolTable.Add(c.Token.symbol, new List <ParseNode>()
                            {
                                c
                            });
                        }
                        catch (ArgumentException)
                        {
                            symbolTable[c.Token.symbol].Add(c);
                        } //Thrown when the key is already present, so at it to the current list.
                    }

                    wSet.Push(c);
                }
                catch (InvalidOperationException)
                {
                    //An operator was not able to pop its needed
                    //operands from the working set.
                    Error        = pt;
                    ErrorMessage = string.Format("Too few operands for {0}.", pt.symbol);
                    return(null);
                }
            }

            if (wSet.Count == 0)
            {
                //We lost out root?
                throw new Exception();
            }

            if (wSet.Count > 1)
            {
                //If there are still things in the wSet more than
                //one thing left in the stack there was too many
                //operands for the operators.
                while (wSet.Peek().IsOperator&& wSet.Count > 1)
                {
                    wSet.Pop();
                }
                Error        = wSet.Peek().Token;
                ErrorMessage = string.Format(
                    "Unused operands starting w/ {0}.", wSet.Peek().Token.symbol);
                return(null);
            }

            Error        = null;
            ErrorMessage = null;
            return(new ParseTree(wSet.Pop(), symbolTable));
        }