Accord.Fuzzy.Rule.ParseRule C# (CSharp) Method

ParseRule() private method

Converts the Fuzzy Rule to RPN (Reverse Polish Notation). For debug proposes, the string representation of the RPN expression can be acessed by calling GetRPNExpression method.
private ParseRule ( ) : void
return void
        private void ParseRule( )
        {
            // flag to incicate we are on consequent state
            bool consequent = false;

            // tokens like IF and THEN will be searched always in upper case
            string upRule = rule.ToUpper( );

            // the rule must start with IF, and must have a THEN somewhere
            if ( !upRule.StartsWith( "IF" ) )
                throw new ArgumentException( "A Fuzzy Rule must start with an IF statement." );
            if ( upRule.IndexOf( "THEN" ) < 0 )
                throw new ArgumentException( "Missing the consequent (THEN) statement." );

            // building a list with all the expression (rule) string tokens
            string spacedRule = rule.Replace( "(", " ( " ).Replace( ")", " ) " );
            // getting the tokens list
            string[] tokensList = GetRuleTokens( spacedRule );

            // stack to convert to RPN
            Stack<string> s = new Stack<string>( );
            // storing the last token
            string lastToken = "IF";
            // linguistic var read, used to build clause
            LinguisticVariable lingVar = null;

            // verifying each token
            for ( int i = 0; i < tokensList.Length; i++ )
            {
                // removing spaces
                string token = tokensList[i].Trim( );
                // getting upper case
                string upToken = token.ToUpper( );

                // ignoring these tokens
                if ( upToken == "" || upToken == "IF" ) continue;

                // if the THEN is found, the rule is now on consequent
                if ( upToken == "THEN" )
                {
                    lastToken = upToken;
                    consequent = true;
                    continue;
                }

                // if we got a linguistic variable, an IS statement and a label is needed
                if ( lastToken == "VAR" )
                {
                    if ( upToken == "IS" )
                        lastToken = upToken;
                    else
                        throw new ArgumentException( "An IS statement is expected after a linguistic variable." );
                }
                // if we got an IS statement, a label must follow it
                else if ( lastToken == "IS" )
                {
                    try
                    {
                        FuzzySet fs = lingVar.GetLabel( token );
                        Clause c = new Clause( lingVar, fs );
                        if ( consequent )
                            output = c;
                        else
                            rpnTokenList.Add( c );
                        lastToken = "LAB";
                    }
                    catch ( KeyNotFoundException )
                    {
                        throw new ArgumentException( "Linguistic label " + token + " was not found on the variable " + lingVar.Name + "." );
                    }
                }
                // not VAR and not IS statement 
                else
                {
                    // openning new scope
                    if ( upToken == "(" )
                    {
                        // if we are on consequent, only variables can be found
                        if ( consequent )
                            throw new ArgumentException( "Linguistic variable expected after a THEN statement." );
                        // if its a (, just push it
                        s.Push( upToken );
                        lastToken = upToken;
                    }
                    // operators
                    else if ( upToken == "AND" || upToken == "OR" || unaryOperators.IndexOf( upToken ) >= 0 )
                    {
                        // if we are on consequent, only variables can be found
                        if ( consequent )
                            throw new ArgumentException( "Linguistic variable expected after a THEN statement." );

                        // pop all the higher priority operators until the stack is empty 
                        while ( ( s.Count > 0 ) && ( Priority( s.Peek( ) ) > Priority( upToken ) ) )
                            rpnTokenList.Add( s.Pop( ) );

                        // pushing the operator    
                        s.Push( upToken );
                        lastToken = upToken;
                    }
                    // closing the scope
                    else if ( upToken == ")" )
                    {
                        // if we are on consequent, only variables can be found
                        if ( consequent )
                            throw new ArgumentException( "Linguistic variable expected after a THEN statement." );

                        // if there is nothing on the stack, an oppening parenthesis is missing.
                        if ( s.Count == 0 )
                            throw new ArgumentException( "Openning parenthesis missing." );

                        // pop the tokens and copy to output until openning is found 
                        while ( s.Peek( ) != "(" )
                        {
                            rpnTokenList.Add( s.Pop( ) );
                            if ( s.Count == 0 )
                                throw new ArgumentException( "Openning parenthesis missing." );
                        }
                        s.Pop( );

                        // saving last token...
                        lastToken = upToken;
                    }
                    // finally, the token is a variable
                    else
                    {
                        // find the variable
                        try
                        {
                            lingVar = database.GetVariable( token );
                            lastToken = "VAR";
                        }
                        catch ( KeyNotFoundException )
                        {
                            throw new ArgumentException( "Linguistic variable " + token + " was not found on the database." );
                        }
                    }
                }
            }

            // popping all operators left in stack
            while ( s.Count > 0 )
                rpnTokenList.Add( s.Pop( ) );
        }