public void BasicTest() { var target = new Parenthesis(); Assert.IsNotNull(target.AllResults); Assert.AreEqual(5, target.AllResults.Count()); }
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()); }
/// <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); }
private void CreateParenthesis(Parenthesis parenthesis, string value = "") { IWhere exp = new Where(WhereType.None, LogicOperator, parenthesis) { Value = value, TableAlias = TableAlias }; Append(exp); }
/// <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!"); } }
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); } }
private void CurrentParen() { currentParen = currentScope.parentheses[currentScope.parentheses.Count() - 1]; }
public static bool IsParenthesis(this IToken token, Parenthesis parenthesis) { var parenthesisToken = token as ParenthesisToken; return(parenthesisToken != null && parenthesisToken.Value == parenthesis); }
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; }
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; }
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] + "'"), });