/// <summary> /// Adds an expression to this /// </summary> /// <param name="expr">Expression to add</param> /// <param name="addToFirst">Whether to add expression as first expression</param> public void AddExpression(Expression expr, bool addToFirst) { if ( addToFirst ) { FirstExpression = expr; } else { SecondExpression = expr; } }
/// <summary> /// Creates a new print statement /// </summary> /// <param name="expression">Expression to print</param> public StatementPrint(Expression expression) { Expression = expression; }
/// <summary> /// Handles the "op" production /// </summary> private void Operator(Expression expression) { var token = NextToken(); if (token == null) { AddSyntaxError(null, "operator symbol"); return; } if ( token.Lexeme == Operators.Plus || token.Lexeme == Operators.Minus || token.Lexeme == Operators.Multiply || token.Lexeme == Operators.Divide || token.Lexeme == Operators.LesserThan || token.Lexeme == Operators.GreaterThan || token.Lexeme == Operators.LesserOrEqualThan || token.Lexeme == Operators.GreaterOrEqualThan || token.Lexeme == Operators.Equal || token.Lexeme == Operators.NotEqual || token.Lexeme == Operators.And ) { expression.Operator = token; return; } var op = new List<string> { Operators.Plus, Operators.Minus, Operators.Multiply, Operators.Divide, Operators.LesserThan, Operators.GreaterThan, Operators.LesserOrEqualThan, Operators.GreaterOrEqualThan, Operators.Equal, Operators.NotEqual, Operators.And }; AddSyntaxError(token, String.Join(", ", op)); SkipTokensUntilExpression(new List<string>()); }
/// <summary> /// Handles the "opnd" production /// </summary> private void Operand(Expression expression, bool addToFirst) { var token = NextToken(); if (token == null) { AddSyntaxError(null, "int, string, bool, (, or variable identifier"); return; } var tokenInt = token as TokenTerminal<int>; if ( tokenInt != null) { expression.AddOperand(tokenInt, addToFirst); return; } var tokenString = token as TokenTerminal<string>; if (tokenString != null) { expression.AddOperand(tokenString, addToFirst); return; } if (token is TokenIdentifier) { _i--; Identifier(); expression.AddOperand(token as TokenIdentifier, addToFirst); return; } if ( CheckToken(token, Operators.ParenthesisLeft) ) { var expr = Expression(); token = NextToken(); if ( !CheckToken(token, Operators.ParenthesisRight) ) { AddSyntaxError(token, Operators.ParenthesisRight); } expression.AddExpression(expr, addToFirst); return; } _i--; var unary = OperandAlt(); var tokenBool = NextToken() as TokenTerminal<bool>; if (tokenBool == null) { AddSyntaxError(null, "bool"); return; } tokenBool.Value = unary && tokenBool.Value; expression.AddOperand(tokenBool, addToFirst); }
/// <summary> /// Handles the "expr'" production /// </summary> private void ExpressionAlt(Expression expression) { var token = CurrentToken(); if (CheckToken(token, ReservedKeywords.Semicolon) || CheckToken(token, ReservedKeywords.Range) || CheckToken(token, ReservedKeywords.Do) || CheckToken(token, Operators.ParenthesisRight) ) { return; } if (token != null && FirstStatement.Contains(token.Lexeme) || token is TokenIdentifier) { // syntax error return; } Operator(expression); Operand(expression, false); }
/// <summary> /// Handles the "expr" production /// </summary> private Expression Expression() { var expr = new Expression(); Operand(expr, true); ExpressionAlt(expr); return expr; }
/// <summary> /// Extracts string value from expression /// </summary> /// <param name="expression">Expression</param> /// <returns>String value</returns> private static string ExtractString(Expression expression) { try { return expression.EvaluateInt().ToString(); } catch ( AbstractSyntaxTreeException ) { Statements.DeleteLastAddedError(); } try { return expression.EvaluateBool().ToString().ToLower(); } catch ( AbstractSyntaxTreeException ) { Statements.DeleteLastAddedError(); } return expression.EvaluateString(); }
/// <summary> /// Calculates boolean value from two expressions /// </summary> /// <param name="first">First expression</param> /// <param name="op">Operator</param> /// <param name="second">Second expression</param> /// <returns>Result</returns> private static bool CalculateBool(Expression first, string op, Expression second) { try { var b1 = first.EvaluateBool(); var b2 = second.EvaluateBool(); return Calculate(first.GetFirstNotNullToken(), b1, op, b2); } catch ( AbstractSyntaxTreeException ) { Statements.DeleteLastAddedError(); } try { var i1 = first.EvaluateInt(); var i2 = second.EvaluateInt(); return Compare(first.GetFirstNotNullToken(), i1, op, i2); } catch ( AbstractSyntaxTreeException ) { Statements.DeleteLastAddedError(); } try { var s1 = first.EvaluateString(); var s2 = second.EvaluateString(); return Compare(first.GetFirstNotNullToken(), s1, op, s2); } catch ( AbstractSyntaxTreeException ) { Statements.DeleteLastAddedError(); } Statements.AddSemanticError(first.GetFirstNotNullToken(), "Could not evaluate value."); throw new AbstractSyntaxTreeCalculateException("Couldn't evaluate."); }
/// <summary> /// Creates a new statement to initialize variables /// </summary> /// <param name="identifier">Variable's identifier</param> /// <param name="type">Variable's type</param> /// <param name="expression">Variable's value</param> public StatementVarInitialize(string identifier, string type, Expression expression) { Identifier = identifier; Type = type; Expression = expression; }