/// <summary>
 ///     Visits a unary expression
 /// </summary>
 /// <param name="unaryExpression"></param>
 protected virtual void VisitUnaryExpression(UnaryExpression unaryExpression)
 {
     if (unaryExpression.Expression != null)
     {
         VisitExpression(unaryExpression.Expression);
     }
     if (unaryExpression.Term != null)
     {
         VisitTerm(unaryExpression.Term);
     }
 }
        public override void visit(Generated.RuleCondition obj, bool subNodes)
        {
            Rules.RuleCondition ruleCondition = obj as Rules.RuleCondition;

            if (ruleCondition != null)
            {
                try
                {
                    bool found = false;
                    ruleCondition.Messages.Clear();

                    foreach (Rules.PreCondition preCondition in ruleCondition.PreConditions)
                    {
                        Interpreter.BinaryExpression expression = checkExpression(preCondition, preCondition.Expression) as Interpreter.BinaryExpression;
                        if (expression != null)
                        {
                            if (expression.IsSimpleEquality())
                            {
                                Types.ITypedElement variable = expression.Left.Ref as Types.ITypedElement;
                                if (variable != null)
                                {
                                    if (variable.Type != null)
                                    {
                                        // Check that when preconditions are based on a request,
                                        // the corresponding action affects the value Request.Disabled to the same variable
                                        if (variable.Type.Name.Equals("Request") && expression.Right != null && expression.Right is Interpreter.UnaryExpression)
                                        {
                                            Values.IValue val2 = expression.Right.Ref as Values.IValue;
                                            if (val2 != null && "Response".CompareTo(val2.Name) == 0)
                                            {
                                                if (ruleCondition != null)
                                                {
                                                    found = false;
                                                    foreach (Rules.Action action in ruleCondition.Actions)
                                                    {
                                                        Variables.IVariable var = OverallVariableFinder.INSTANCE.findByName(action, preCondition.findVariable());
                                                        Interpreter.Statement.VariableUpdateStatement update = action.Modifies(var);
                                                        if (update != null)
                                                        {
                                                            Interpreter.UnaryExpression updateExpr = update.Expression as Interpreter.UnaryExpression;
                                                            if (updateExpr != null)
                                                            {
                                                                Values.IValue val3 = updateExpr.Ref as Values.IValue;
                                                                if (val3 != null && val3.Name.CompareTo("Disabled") == 0)
                                                                {
                                                                    found = true;
                                                                    break;
                                                                }
                                                            }
                                                        }
                                                    }

                                                    if (!found)
                                                    {
                                                        preCondition.AddError("Rules where the Pre conditions is based on a Request type variable must assign that variable the value 'Request.Disabled'");
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    // Check that the outgoing variables are not read
                                    if (variable.Mode == Generated.acceptor.VariableModeEnumType.aOutgoing)
                                    {
                                        if (ruleCondition.Reads(variable))
                                        {
                                            preCondition.AddError("An outgoing variable cannot be read");
                                        }
                                    }

                                    // Check that the incoming variables are not modified
                                    if (variable.Mode == Generated.acceptor.VariableModeEnumType.aIncoming)
                                    {
                                        if (ruleCondition.Modifies(variable) != null)
                                        {
                                            preCondition.AddError("An incoming variable cannot be written");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception exception)
                {
                    ruleCondition.AddException(exception);
                }
            }

            base.visit(obj, subNodes);
        }
        /// <summary>
        ///     Evaluates a unary expression
        ///     . NOT expression
        ///     . Term
        /// </summary>
        /// <returns></returns>
        private Expression EvaluateUnaryExpression()
        {
            Expression retVal;

            SkipWhiteSpaces();
            int start = Index;
            string unaryOp = LookAhead(UnaryExpression.UnaryOperators);
            if (unaryOp != null)
            {
                Match(unaryOp);
                Expression expression = Expression(6);
                retVal = new UnaryExpression(Root, RootLog, expression, unaryOp, start, Index);
            }
            else
            {
                if (LookAhead("STABILIZE"))
                {
                    Match("STABILIZE");
                    Expression expression = Expression(0);
                    Match("INITIAL_VALUE");
                    Expression initialValue = Expression(0);
                    Match("STOP_CONDITION");
                    Expression condition = Expression(0);

                    retVal = new StabilizeExpression(Root, RootLog, expression, initialValue, condition, start, Index);
                }
                else
                {
                    retVal = EvaluateStructure();
                    if (retVal == null)
                    {
                        retVal = EvaluateFunction();
                    }
                    if (retVal == null)
                    {
                        Term term = Term();
                        if (term != null)
                        {
                            retVal = new UnaryExpression(Root, RootLog, term, start, Index);
                        }
                        else if (LookAhead("("))
                        {
                            Match("(");
                            retVal = new UnaryExpression(Root, RootLog, Expression(0), null, start, -1);
                            Match(")");
                            retVal.End = Index;

                            retVal = Continuation(retVal);
                        }
                    }
                }
            }

            return retVal;
        }
        /// <summary>
        ///     Creates a redef expression based on the input of the parser
        /// </summary>
        /// <returns></returns>
        private Expression DerefExpression()
        {
            Expression retVal = null;

            List<Expression> derefArguments = new List<Expression>();
            SkipWhiteSpaces();
            int start = Index;
            string id = Identifier();
            while (id != null)
            {
                Designator designator = new Designator(Root, RootLog, id, start, start + id.Length);
                Term term = new Term(Root, RootLog, designator, designator.Start, designator.End);
                UnaryExpression unaryExpression = new UnaryExpression(Root, RootLog, term, term.Start, term.End);
                derefArguments.Add(unaryExpression);

                id = null;
                if (LookAhead("."))
                {
                    Match(".");
                    SkipWhiteSpaces();
                    start = Index;
                    id = Identifier();
                }
            }

            if (derefArguments.Count == 1)
            {
                retVal = derefArguments[0];
            }
            else if (derefArguments.Count > 1)
            {
                retVal = new DerefExpression(Root, RootLog, derefArguments, derefArguments[0].Start,
                    derefArguments[derefArguments.Count - 1].End);
            }

            return retVal;
        }
        /// <summary>
        /// Evaluates a unary expression
        ///  . NOT expression
        ///  . Term
        /// </summary>
        /// <param name="enclosing"></param>
        /// <returns></returns>
        private Expression EvaluateUnaryExpression()
        {
            Expression retVal = null;

            string unaryOp = LookAhead(UnaryExpression.UNARY_OPERATORS);
            if (unaryOp != null)
            {
                Match(unaryOp);
                Expression expression = Expression(6);
                retVal = new UnaryExpression(Root, expression, unaryOp);
            }
            else
            {
                if (LookAhead("STABILIZE"))
                {
                    Match("STABILIZE");
                    Expression expression = Expression(0);
                    Match("INITIAL_VALUE");
                    Expression initialValue = Expression(0);
                    Match("STOP_CONDITION");
                    Expression condition = Expression(0);

                    retVal = new StabilizeExpression(Root, expression, initialValue, condition);
                }
                else
                {
                    retVal = EvaluateStructure();
                    if (retVal == null)
                    {
                        retVal = EvaluateFunction();
                    }
                    if (retVal == null)
                    {
                        Term term = Term();
                        if (term != null)
                        {
                            retVal = new UnaryExpression(Root, term);
                        }
                        else if (LookAhead("("))
                        {
                            Match("(");
                            retVal = new UnaryExpression(Root, Expression(0));
                            Match(")");

                            if (retVal != null)
                            {
                                retVal = Continuation(retVal);
                            }
                        }
                    }
                }
            }

            return retVal;
        }
        /// <summary>
        /// Creates a redef expression based on the input of the parser
        /// </summary>
        /// <returns></returns>
        private Expression DerefExpression()
        {
            Expression retVal = null;

            List<Expression> derefArguments = new List<Expression>();
            string id = Identifier();
            while (id != null)
            {
                Designator designator = new Interpreter.Designator(Root, id);
                Term term = new Term(Root, designator);
                UnaryExpression unaryExpression = new UnaryExpression(Root, term);
                derefArguments.Add(unaryExpression);

                id = null;
                if (LookAhead("."))
                {
                    Match(".");
                    id = Identifier();
                }
            }

            if (derefArguments.Count == 1)
            {
                retVal = derefArguments[0];
            }
            else if (derefArguments.Count > 1)
            {
                retVal = new DerefExpression(Root, derefArguments);
            }

            return retVal;
        }
 /// <summary>
 ///     Visits a unary expression
 /// </summary>
 /// <param name="unaryExpression"></param>
 protected virtual void VisitUnaryExpression(UnaryExpression unaryExpression)
 {
     if (unaryExpression.Expression != null)
     {
         VisitInterpreterTreeNode(unaryExpression.Expression);
     }
     if (unaryExpression.Term != null)
     {
         VisitInterpreterTreeNode(unaryExpression.Term);
     }
 }