// TODO: at the end we need to add to stack new function
        public bool Visit(CallableDeclNode node)
        {
            node.Header.Accept(this);

            var existedCallable = _symStack.FindFunc(node.Header.CallableSymbol.Ident,
                                                     new List <SymType>(from type in node.Header.CallableSymbol.ParametersTypes select type.Item2));

            if (existedCallable != null)
            {
                if (!existedCallable.IsForward)
                {
                    throw new Exception(string.Format(
                                            "({0}, {1}) semantic error: overloaded functions have the same parameter list",
                                            node.Header.Name.Token.Line, node.Header.Name.Token.Column));
                }

                var modifiersAreSame = true;
                for (var i = 0; i < existedCallable.ParametersTypes.Count; ++i)
                {
                    if (existedCallable.ParametersTypes[i].Item1 ==
                        node.Header.CallableSymbol.ParametersTypes[i].Item1)
                    {
                        continue;
                    }
                    modifiersAreSame = false;
                    break;
                }

                if (!modifiersAreSame)
                {
                    throw new Exception(string.Format(
                                            "({0}, {1}) semantic error: function does not match the previous declaration",
                                            node.Header.Name.Token.Line, node.Header.Name.Token.Column));
                }
            }
            else
            {
                _symStack.PrepareFunction(node.Header.CallableSymbol);
            }

            if (node.Block != null)
            {
                _symStack.Push(node.Header.CallableSymbol.Local);
                node.Header.CallableSymbol.IsForward = false;
                _inLastNamespace = true;
                node.Block.Accept(this);
                _inLastNamespace = false;
                node.Header.CallableSymbol.Local = _symStack.Pop();
                _symStack.AddFunction(node.Header.CallableSymbol);
            }
            else if (existedCallable != null)
            {
                throw new Exception(string.Format(
                                        "({0}, {1}) semantic error: function is already declared",
                                        node.Header.Name.Token.Line, node.Header.Name.Token.Column));
            }

            return(true);
        }
Esempio n. 2
0
        public bool Validate(List <Token> tokens, int idx = -1)
        {
            Token currentToken = null;

            CurrentState = CurrentState.GoToNextState(TokenEnums.TokenType.Dollar); // move from the initialstate going forward

            try
            {
                for (int i = idx; i < tokens.Count;)
                {
                    if (CurrentState.StateAction == StateAction.Accept)
                    {
                        break;
                    }
                    if (CurrentState.StateAction == StateAction.Scan)
                    {
                        // do nothing
                        i++;
                        currentToken = i >= 0 ? tokens[i] : null;
                    }
                    else if (CurrentState.StateAction == StateAction.Read && currentToken.TokenType == TokenEnums.TokenType.Tag)
                    {
                        if (TagStack.Peek() == currentToken.Symbol)
                        {
                            TagStack.Pop();
                        }
                    }
                    else if (CurrentState.StateAction == StateAction.Read && (currentToken.TokenType == TokenEnums.TokenType.HeaderXmlOpeningSymbol || currentToken.TokenType == TokenEnums.TokenType.HeaderXmlClosingSymbol || currentToken.TokenType == TokenEnums.TokenType.ClosingSymbol || currentToken.TokenType == TokenEnums.TokenType.OpeningSymbol || currentToken.TokenType == TokenEnums.TokenType.OpeningWithBackslashSymbol || currentToken.TokenType == TokenEnums.TokenType.SelfClosingSymbol))
                    {
                        if (currentToken.TokenType == TokenEnums.TokenType.SelfClosingSymbol || currentToken.TokenType == TokenEnums.TokenType.HeaderXmlClosingSymbol)
                        {
                            TagStack.Pop();
                        }
                        var peek = SymbolStack.Peek();
                        if ((currentToken.Partners != null && currentToken.Partners.Any(item => item == peek)) || peek == currentToken.Partner)
                        {
                            SymbolStack.Pop();
                        }
                        // TO DO: handle partner tags
                    }
                    else if (CurrentState.StateAction == StateAction.Write && (currentToken.TokenType == TokenEnums.TokenType.Tag || currentToken.TokenType == TokenEnums.TokenType.HeaderXmlTag))
                    {
                        TagStack.Push(currentToken.Symbol);
                    }
                    else if (CurrentState.StateAction == StateAction.Write && (currentToken.TokenType == TokenEnums.TokenType.HeaderXmlClosingSymbol || currentToken.TokenType == TokenEnums.TokenType.HeaderXmlOpeningSymbol || currentToken.TokenType == TokenEnums.TokenType.ClosingSymbol || currentToken.TokenType == TokenEnums.TokenType.OpeningSymbol || currentToken.TokenType == TokenEnums.TokenType.OpeningWithBackslashSymbol || currentToken.TokenType == TokenEnums.TokenType.SelfClosingSymbol))
                    {
                        SymbolStack.Push(currentToken.Symbol);
                    }
                    var nextState = CurrentState.GoToNextState(currentToken.TokenType); // move from the initialstate going forward

                    if (nextState == null)
                    {
                        //// non-deterministic
                        //// guess next state based on next token
                        var nextToken = (i + 1) >= tokens.Count ? null : tokens[i + 1];
                        if (nextToken != null)
                        {
                            var states = CurrentState.GetPossibleNextStates(currentToken.TokenType);
                            nextState = states.Where(state => state.StateAction != StateAction.Accept).FirstOrDefault();
                        }
                        else
                        {
                            // end state
                            var states = CurrentState.GetPossibleNextStates(currentToken.TokenType);
                            nextState = states.Where(state => state.StateAction == StateAction.Accept).FirstOrDefault();
                        }
                    }

                    CurrentState = nextState;
                }
            }
            catch (Exception ex)
            {
                throw;
            }

            // scan
            //foreach (var item in tokens)
            //{
            //    if (item.TokenType == TokenEnums.TokenType.Tag)
            //    {
            //        if (tags.Count != 0 && tags.Peek() == item.Symbol)
            //        {
            //            tags.Pop();
            //        }
            //        else
            //        {
            //            tags.Push(item.Symbol);

            //        }
            //    }
            //    else if (item.TokenType == TokenEnums.TokenType.OpeningSymbol || item.TokenType == TokenEnums.TokenType.OpeningWithBackslashSymbol)
            //    {
            //        symbols.Push(item);
            //    }
            //    else if (symbols.Count != 0 && item.TokenType == TokenEnums.TokenType.ClosingSymbol)
            //    {
            //        if (symbols.Peek().TokenType == TokenEnums.TokenType.OpeningSymbol || symbols.Peek().TokenType == TokenEnums.TokenType.OpeningWithBackslashSymbol)
            //        {
            //            symbols.Pop();
            //        }
            //    }
            //    else if (item.TokenType == TokenEnums.TokenType.SelfClosingSymbol)
            //    {
            //        tags.Pop();
            //    }
            //}

            if (TagStack.Count == 0 && SymbolStack.Count == 0 && CurrentState == FinalState)
            {
                return(true);
            }



            return(false);
        }