Ejemplo n.º 1
0
        public void BasicTest()
        {
            var target = new Parenthesis();

            Assert.IsNotNull(target.AllResults);
            Assert.AreEqual(5, target.AllResults.Count());
        }
Ejemplo n.º 2
0
        public void VariationTest()
        {
            var target = new Parenthesis("{}", 6);

            Assert.IsNotNull(target.AllResults);
            Assert.AreEqual(132, target.AllResults.Count());
        }
    /// <summary>
    /// Creates an infix notation (3 4 2 * 1 5 - 2 3 ^ ^ / +) from a postfix notation (3 + 4 * 2 / ( 1 / 5 ) ^ 2 ^ 3)
    /// </summary>
    /// <param name="tokens">Tokens from which to create the infix</param>
    /// <returns>An infix notation created from the given postfix</returns>
    private static List <Token> FromPostfixToInfix(List <Token> tokens)
    {
        Queue <Token> output    = new Queue <Token>();
        Stack <Token> operators = new Stack <Token>();

        for (int i = 0; i < tokens.Count; i++)
        {
            // these need to be pushed directly in the output queue
            if (tokens[i] is Number || tokens[i] is X || tokens[i] is Function)
            {
                output.Enqueue(tokens[i]);
            }
            else if (tokens[i] is Operator)
            {
                Operator currOp = (Operator)tokens[i];

                // while...
                while (operators.Count > 0 &&
                       (operators.Peek() is Operator &&           // The top is an operator (needed for the two lines below)
                        (((Operator)operators.Peek()) > currOp || // with a greater precedence
                                                                  // OR with the same precedence and is left associative
                         ((Operator)operators.Peek()) == currOp && !((Operator)operators.Peek()).attribute.rightAssociative)))
                {
                    output.Enqueue(operators.Pop());
                }
                operators.Push(currOp); // push operator to the operators stack
            }
            else if (tokens[i] is Parenthesis)
            {
                Parenthesis currPar = (Parenthesis)tokens[i];

                // left/open parenthesis need to be pushed on the operator stack
                if (currPar.open)
                {
                    operators.Push(currPar);
                }
                else     // right/closing parenthesis
                {
                    try {
                        // while top operator is not left bracket (something else or right bracket)
                        while (!(operators.Peek() is Parenthesis) || (operators.Peek() is Parenthesis && !((Parenthesis)operators.Peek()).open))
                        {
                            output.Enqueue(operators.Pop());
                        }
                    } catch (InvalidOperationException e) {
                        throw new InputException("No closing parenthesis!", e, -1);
                    }
                    operators.Pop();
                }
            }
        }

        // while we have operators on the stack add it to the queue
        while (operators.Count > 0)
        {
            output.Enqueue(operators.Pop());
        }

        return(output.ToList());
    }
Ejemplo n.º 4
0
        /// <summary>
        /// Parse a string and returns a value
        /// </summary>
        /// <param name="code">The ILA coded string</param>
        /// <param name="mainProg">The algo from where the value comes</param>
        /// <param name="currentBlock">the scope from where the value comes</param>
        /// <param name="constLock">true if the value has to be constant (false by default)</param>
        /// <returns>parsed value</returns>
        public static IValue ParseValue(string code, Program mainProg, IExecutable currentBlock, bool constLock = false)
        {
            var decomposed = Parenthesis.Generate(code);
            var res        = ParseParenthesis(decomposed, mainProg, currentBlock, constLock);

            return(res);
        }
Ejemplo n.º 5
0
        private void CreateParenthesis(Parenthesis parenthesis, string value = "")
        {
            IWhere exp = new Where(WhereType.None, LogicOperator, parenthesis)
            {
                Value      = value,
                TableAlias = TableAlias
            };

            Append(exp);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Same as Rule just with observation
        /// </summary>
        /// <param name="list"> list of atomic expressions </param>
        /// <returns>
        /// Packed observation object, and a list containing all the
        /// ConcreteObservations in the packed object
        ///  </returns>
        public static Tuple <Observation, List <ConcreteObservation> > ObservationConversion(List <AtomicExpression> list)
        {
            var stack = new Stack <object>();
            var concreteObservations = new List <ConcreteObservation>();
            var lastExpressionString = string.Empty;

            try
            {
                foreach (var expression in list)
                {
                    // variable
                    if (!string.IsNullOrEmpty(expression.Value))
                    {
                        ConcreteObservation concreteObservation = MainWindow.GetCachedObservationByName(expression.Value);
                        concreteObservations.Add(concreteObservation);

                        stack.Push(concreteObservation);
                        continue;
                    }
                    // unary operator
                    object result;
                    if (expression.Operator == "-")
                    {
                        Observation tmpEval = stack.Pop() as Observation;
                        if (tmpEval.GetType() != typeof(ConcreteObservation))
                        {
                            tmpEval = new Parenthesis(tmpEval);
                        }
                        result = expression.Evaluate(tmpEval);
                    }
                    // binary operator
                    else
                    {
                        var         p2      = stack.Pop();
                        var         p1      = stack.Pop();
                        Observation tmpEval = expression.Evaluate(p1, p2);

                        if (expression.Operator == "ILI" && (lastExpressionString == "I" || lastExpressionString == "-"))
                        {
                            tmpEval = new Parenthesis(tmpEval);
                        }

                        result = tmpEval;
                    }
                    stack.Push(result);
                    lastExpressionString = expression.Operator;
                }
                var observation = stack.Pop() as Observation;
                return(new Tuple <Observation, List <ConcreteObservation> >(observation, concreteObservations));
            }
            catch (InvalidOperationException e)
            {
                throw new ParsingException("parsing failed, reenter your expression!");
            }
        }
Ejemplo n.º 7
0
        Token InflateToken(TokenInfo tokenInfo)
        {
            string    match     = tokenInfo.Pattern;
            TokenType tokenType = tokenInfo.Type;

            switch (tokenType)
            {
            case TokenType.Variable:
                return(Variable.New(match));

            case TokenType.Constant:
                return(InflateConstantToken(match));

            case TokenType.ParenLeft:
                return(Parenthesis.NewLeft());

            case TokenType.ParenRight:
                return(Parenthesis.NewRight());

            case TokenType.OpAdd:
                return(Operator.NewAddition());

            case TokenType.OpSubtract:
                return(Operator.NewSubtraction());

            case TokenType.OpMultiply:
                return(Operator.NewMultiplication());

            case TokenType.OpDivide:
                return(Operator.NewDivision());

            case TokenType.OpPower:
                return(Operator.NewPower());

            case TokenType.Function:
                return(FunctionHeader.New(match, match.Substring(0, 1).ToUpper() + match.Substring(1), 1));

            default:
                return(null);
            }
        }
Ejemplo n.º 8
0
 private void CurrentParen()
 {
     currentParen = currentScope.parentheses[currentScope.parentheses.Count() - 1];
 }
Ejemplo n.º 9
0
        public static bool IsParenthesis(this IToken token, Parenthesis parenthesis)
        {
            var parenthesisToken = token as ParenthesisToken;

            return(parenthesisToken != null && parenthesisToken.Value == parenthesis);
        }
Ejemplo n.º 10
0
 private Expression ParseParenthesizedExpression(bool keepParentheses, TokenSet followers)
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder sctx = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   if (this.currentToken == Token.LeftBrace) {
     Expression dummy = new DummyExpression(sctx);
     this.SkipTo(followers, Error.SyntaxError, "(");
     return dummy;
   }
   this.Skip(Token.LeftParenthesis);
   Expression result = this.ParseExpression(followers|Token.RightParenthesis|Token.Colon);
   if (keepParentheses) {
     sctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
     result = new Parenthesis(result, sctx);
   }
   this.SkipOverTo(Token.RightParenthesis, followers);
   return result;
 }
Ejemplo n.º 11
0
 private Expression ParseParenthesizedExpression(TokenSet followers)
   //^ requires this.currentToken == Token.LeftParens;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder sctx = new SourceLocationBuilder(this.scanner.CurrentSourceLocation);
   this.GetNextToken();
   Expression result = this.ParseExpression(followers|Token.RightParens|Token.EndOfLine);
   sctx.UpdateToSpan(this.scanner.CurrentSourceLocation);
   result = new Parenthesis(result, sctx);
   this.SkipOverTo(Token.RightParens, followers|Token.EndOfLine);
   return result;
 }
Ejemplo n.º 12
0
        internal static IValue ParseOperand(string code, Program mainProg, IExecutable currentBlock, Parenthesis p, bool constLock)
        {
            code = code.Trim();
            if (code.Length == 0)
            {
                //fct/tab call
                if (p.FunctionName != null)
                {
                    if (constLock)
                    {
                        throw new ILAException("Erreur impossible de donner une valeur non constante");
                    }
                    var call = new FunctionCall();
                    call.CalledFunction = null;
                    call.Args           = new List <IValue>();
                    foreach (var item in mainProg.Methods)
                    {
                        if (item.Name == p.FunctionName && item is Function f)
                        {
                            call.CalledFunction = f;
                            break;
                        }
                    }
                    if (call.CalledFunction == null)
                    {
                        throw new ILAException("Aucune fonction nommée '" + p.FunctionName + "' trouvée");
                    }
                    foreach (var item in p.FctIndexes)
                    {
                        call.Args.Add(ParseParenthesis(item, mainProg, currentBlock, constLock));
                    }
                    return(call);
                }
                else if (p.TabName != null)
                {
                    if (constLock)
                    {
                        throw new ILAException("Erreur impossible de donner une valeur non constante");
                    }
                    var call = new TableCall();
                    call.Table           = null;
                    call.DimensionsIndex = new List <IValue>();
                    foreach (var item in currentBlock.Declarations)
                    {
                        if (item is VariableDeclaration vd && vd.CreatedVariable.Name == p.TabName)
                        {
                            call.Table = vd.CreatedVariable;
                            break;
                        }
                    }
                    if (call.Table == null)
                    {
                        throw new ILAException("Aucune variable nommée '" + p.TabName + "' trouvée");
                    }
                    foreach (var item in p.TabIndexes)
                    {
                        call.DimensionsIndex.Add(ParseParenthesis(item, mainProg, currentBlock, constLock));
                    }
                    return(call);
                }
                else
                {
                    return(null);
                }
            }
            int index = Max(
                code.LastIndexOf('='),
                code.LastIndexOf('☻'),
                code.LastIndexOf('♥'),
                code.LastIndexOf('♦'),
                code.LastIndexOf('<'),
                code.LastIndexOf('>')
                );

            if (index == -1)
            {
                index = code.LastIndexOf('•');
                if (index == -1)
                {
                    index = code.LastIndexOf('◘');
                    if (index == -1)
                    {
                        index = Max(
                            code.LastIndexOf('+'),
                            code.LastIndexOf('-')
                            );
                        if (index == -1)
                        {
                            index = Max(
                                code.LastIndexOf('♣'),
                                code.LastIndexOf('♠'),
                                code.LastIndexOf('*'),
                                code.LastIndexOf('/')
                                );
                            if (index == -1)
                            {
                                //non <val>, ?####, variable, constant, enum, unary minus
                                if (code.First() == '○') //non
                                {
                                    var op = new Operator();
                                    op.Left         = null;
                                    op.OperatorType = Operator.Tag.NOT;
                                    op.Right        = ParseOperand(code.Substring(1), mainProg, currentBlock, p, constLock);
                                    return(op);
                                }
                                else if (code.First() == '◙') //unary minus
                                {
                                    var op = new Operator();
                                    op.Left         = null;
                                    op.OperatorType = Operator.Tag.MINUS;
                                    op.Right        = ParseOperand(code.Substring(1), mainProg, currentBlock, p, constLock);
                                    return(op);
                                }
                                else if (code.First() == '?')//parenthesis group
                                {
                                    int pNumber = int.Parse(code.Substring(1, 4));
                                    return(ParseParenthesis(p.RecursiveParenthesis[pNumber], mainProg, currentBlock, constLock));
                                }
                                else
                                {
                                    //variable, constant, enum
                                    if (IsLetter(code.First()))
                                    {
                                        //variable, enum, bool constant
                                        string n = "";
                                        int    i = 0;
                                        while (IsLetterOrDigit(code[i]))
                                        {
                                            n += code[i++];
                                            if (i == code.Length)
                                            {
                                                break;
                                            }
                                        }
                                        if (n == "vrai")
                                        {
                                            return new ConstantBool()
                                                   {
                                                       Value = true
                                                   }
                                        }
                                        ;
                                        if (n == "faux")
                                        {
                                            return new ConstantBool()
                                                   {
                                                       Value = false
                                                   }
                                        }
                                        ;
                                        //variable, enum
                                        foreach (var decl in mainProg.Declarations)
                                        {
                                            if (decl is TypeDeclaration td && td.CreatedType is EnumType en)
                                            {
                                                for (int j = 0; j < en.Values.Count; j++)
                                                {
                                                    if (en.Values[j] == n)
                                                    {
                                                        //enum call
                                                        return(new EnumCall()
                                                        {
                                                            Enum = en,
                                                            Index = j
                                                        });
                                                    }
                                                }
                                            }
                                        }
                                        //variable
                                        index = -1;
                                        {
                                            int opened = 0;

                                            for (int j = 0; j < code.Length; j++)
                                            {
                                                if ((code[j] == '[' || code[j] == '.') && opened == 0)
                                                {
                                                    index = j;
                                                }
                                                if (code[j] == '[')
                                                {
                                                    opened++;
                                                }
                                                if (code[j] == ']')
                                                {
                                                    opened--;
                                                }
                                            }
                                        }
                                        if (index == -1)
                                        {
                                            //simple variable
                                            foreach (var decl in mainProg.Declarations)
                                            {
                                                if (decl is VariableDeclaration vd && vd.CreatedVariable.Name == n)
                                                {
                                                    if (constLock && !vd.CreatedVariable.Constant)
                                                    {
                                                        throw new ILAException("Erreur impossible de donner une valeur non constante");
                                                    }
                                                    return(vd.CreatedVariable);
                                                }
                                            }
                                            foreach (var decl in currentBlock.Declarations)
                                            {
                                                if (decl is VariableDeclaration vd && vd.CreatedVariable.Name == n)
                                                {
                                                    if (constLock && !vd.CreatedVariable.Constant)
                                                    {
                                                        throw new ILAException("Erreur impossible de donner une valeur non constante");
                                                    }
                                                    return(vd.CreatedVariable);
                                                }
                                            }
                                            if (currentBlock is Module m)
                                            {
                                                foreach (var par in m.Parameters)
                                                {
                                                    if (par.ImportedVariable.Name == n)
                                                    {
                                                        return(par.ImportedVariable);
                                                    }
                                                }
                                            }
                                            throw new ILAException("Aucune variable nommée '" + n + "' trouvée");
                                        }
                                        else if (code[index] == '.')
                                        {
                                            //struct call
                                            if (constLock)
                                            {
                                                throw new ILAException("Erreur impossible de donner une valeur non constante");
                                            }
                                            var left    = code.Substring(0, index);
                                            var right   = code.Substring(index + 1);
                                            var leftVar = ParseValue(left, mainProg, currentBlock, constLock) as Variable;
                                            return(new StructCall()
                                            {
                                                Constant = false,
                                                Name = right,
                                                Struct = leftVar
                                            });

                                            throw new ILAException("Erreur : variable '" + n + "' introuvable dans cette portée");
                                        }
                                        else
                                        {
                                            //table call
                                            if (constLock)
                                            {
                                                throw new ILAException("Erreur impossible de donner une valeur non constante");
                                            }
                                            var left       = code.Substring(0, index);
                                            var right      = code.Substring(index + 1);
                                            var leftVar    = ParseValue(left, mainProg, currentBlock, constLock) as Variable;
                                            var opened     = 0;
                                            var args       = new List <string>();
                                            var currentArg = "";
                                            int j          = 0;
                                            while (right[j] != ']' || opened > 0)
                                            {
                                                if (right[j] == '[')
                                                {
                                                    opened++;
                                                }
                                                if (right[j] == ']')
                                                {
                                                    opened--;
                                                }
                                                if (opened == 0 && right[j] == ',')
                                                {
                                                    args.Add(currentArg);
                                                    currentArg = "";
                                                }
                                                else
                                                {
                                                    currentArg += right[j];
                                                }
                                                j++;
                                            }
                                            args.Add(currentArg);
                                            return(new TableCall()
                                            {
                                                Constant = false,
                                                Table = leftVar,
                                                DimensionsIndex = args.Select(a => ParseValue(a, mainProg, currentBlock, constLock)).ToList()
                                            });

                                            throw new ILAException("Erreur : variable '" + n + "' introuvable dans cette portée");
                                        }
                                    }
                                    else
                                    {
                                        //constant
                                        if (char.IsDigit(code.First()))
                                        {
                                            if (code.Contains('.'))
                                            {
                                                //float
                                                try
                                                {
                                                    return(new ConstantFloat()
                                                    {
                                                        Value = float.Parse(code, new CultureInfo("en"))
                                                    });
                                                }
                                                catch (Exception)
                                                {
                                                    throw new ILAException("Erreur, format de nombre incorrect");
                                                }
                                            }
                                            else
                                            {
                                                //int
                                                try
                                                {
                                                    return(new ConstantInt()
                                                    {
                                                        Value = int.Parse(code, new CultureInfo("en"))
                                                    });
                                                }
                                                catch (Exception)
                                                {
                                                    throw new ILAException("Erreur, format de nombre incorrect");
                                                }
                                            }
                                        }
                                        else if (code.First() == '\'')
                                        {
                                            //char
                                            if (code[1] == '\\')
                                            {
                                                if (code[3] != '\'')
                                                {
                                                    throw new ILAException("Erreur, format de caractere incorrect");
                                                }
                                                return((code[2]) switch
                                                {
                                                    '\'' => new ConstantChar()
                                                    {
                                                        Value = '\''
                                                    },
                                                    '"' => new ConstantChar()
                                                    {
                                                        Value = '"'
                                                    },
                                                    '\\' => new ConstantChar()
                                                    {
                                                        Value = '\\'
                                                    },
                                                    'n' => new ConstantChar()
                                                    {
                                                        Value = '\n'
                                                    },
                                                    'r' => new ConstantChar()
                                                    {
                                                        Value = '\r'
                                                    },
                                                    't' => new ConstantChar()
                                                    {
                                                        Value = '\t'
                                                    },
                                                    'b' => new ConstantChar()
                                                    {
                                                        Value = '\b'
                                                    },
                                                    'f' => new ConstantChar()
                                                    {
                                                        Value = '\f'
                                                    },
                                                    _ => throw new ILAException("Erreur : caractère échapé inconnu '\\" + code[2] + "'"),
                                                });