Пример #1
0
        public override SyntaxTreeNode Make(ObjectStream <MyToken> input, MyDiscardDelegate <MyToken> discarder)
        {
            Ensure(input, discarder);

            // Ignora código descartável inicialmente
            input.Discard(discarder);

            if (input.EndOfStream())
            {
                return(null);
            }

            var initialPos = input.GetPosition();
            var token      = input.Next();

            if (token == null || (CalcTwoNumbersTokenClass)token.Class != (CalcTwoNumbersTokenClass)GetTokenClass())
            {
                input.SetPosition(initialPos);
                return(null);
            }

            if (string.IsNullOrEmpty((string)token.Content))
            {
                throw new SyntaxAnalysisException("Invalid content for NUMBER element");
            }

            uint number = 0;

            if (!uint.TryParse((string)token.Content, out number))
            {
                throw new SyntaxAnalysisException("Invalid number value for NUMBER element");
            }

            return(new UIntegerTreeNode(number));
        }
Пример #2
0
        public override MyToken[] Eval(ObjectStream <Char> input, MyDiscardDelegate <char> discarder)
        {
            Ensure(input, discarder);

            // Ignora código descartável inicialmente
            input.Discard(discarder);

            if (input.EndOfStream())
            {
                return(null);
            }

            var  initialPos = input.GetPosition();
            char character  = input.Next();

            if (character != _character)
            {
                input.SetPosition(initialPos);

                return(null);
            }

            var token = new MyToken(
                GetTokenClass(),
                initialPos,
                input.GetPosition(),
                null
                );

            return(new MyToken[] { token });
        }
Пример #3
0
        protected void Ensure <T>(ObjectStream <T> input, MyDiscardDelegate <T> discarder)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            if (discarder == null)
            {
                throw new ArgumentNullException(nameof(discarder));
            }
        }
Пример #4
0
        public override MyToken[] Eval(ObjectStream <Char> input, MyDiscardDelegate <char> discarder)
        {
            Ensure(input, discarder);

            // Ignora código descartável inicialmente
            input.Discard(discarder);

            if (input.EndOfStream())
            {
                return(null);
            }

            var initialPos  = input.GetPosition();
            var foundTokens = new List <MyToken>();

            foreach (var element in _elements)
            {
                var elementTokens = element.Eval(input, discarder);

                // Qualquer elemento do grupo falhando, todo o grupo falha
                if (elementTokens == null)
                {
                    return(null);
                }

                foundTokens.AddRange(elementTokens);
            }

            if (!foundTokens.Any())
            {
                input.SetPosition(initialPos);

                return(null);
            }

            // O próprio elemento de grupo torna-se um token.
            // Isso é util para ser usado como um demarcador
            var token = new MyToken(
                GetTokenClass(),
                initialPos,
                input.GetPosition(),
                null
                );

            var firstToken = new MyToken[] { token };

            // Os demais tokens seguem o demarcador
            return(firstToken.Concat(foundTokens).ToArray());
        }
Пример #5
0
        /// <summary>
        /// Executa a análise léxica.
        /// </summary>
        /// <param name="input">Sequência de caracteres de entrada</param>
        /// <returns>Sequência de tokens</returns>
        /// <exception cref="LexicalAnalysisException">Se houver algum erro durante a análise</exception>
        /// <exception cref="TokenNotFoundException">Se nenhum token for encontrado</exception>
        /// <exception cref="InputNotConsumedCompletelyException">Se a entrada não for completamente consumida</exception>
        public ObjectStream <MyToken> Run(ObjectStream <Char> input)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            MyDiscardDelegate <Char> discarder = (c) => false;

            if (_grammar.OnLexerDiscard != null)
            {
                discarder = _grammar.OnLexerDiscard;
            }

            try
            {
                MyToken[] acquiredTokens = _grammar.RootElement.Eval(input, discarder);

                if (acquiredTokens == null || acquiredTokens.Count() < 1)
                {
                    // TODO: Informar [currentPos] ???
                    throw new TokenNotFoundException();
                }

                // Ignorando qualquer código descartável que tenha restado
                input.Discard(discarder);

                if (!input.EndOfStream())
                {
                    // TODO: Informar [currentPos] ???
                    throw new InputNotConsumedCompletelyException();
                }

                var output = new TokenStream();

                Array.ForEach(acquiredTokens, (token) => output.Push(token));

                return(output);
            }
            catch (LexicalAnalysisException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new LexicalAnalysisException(ex);
            }
        }
Пример #6
0
        public override SyntaxTreeNode Make(ObjectStream <MyToken> input, MyDiscardDelegate <MyToken> discarder)
        {
            Ensure(input, discarder);

            // Ignora código descartável inicialmente
            input.Discard(discarder);

            if (input.EndOfStream())
            {
                return(null);
            }

            var initialPos = input.GetPosition();

            // O primeiro token é só um marcador (etiqueta) pra indicar
            // um elemento válido
            var tag = input.Next();

            if (tag == null || (CalcTwoNumbersTokenClass)tag.Class != (CalcTwoNumbersTokenClass)GetTokenClass())
            {
                input.SetPosition(initialPos);
                return(null);
            }

            var numberLeftNode  = ExpressionElements[0].Make(input, discarder);
            var plusNode        = ExpressionElements[1].Make(input, discarder);
            var numberRightNode = ExpressionElements[2].Make(input, discarder);

            if (numberLeftNode == null || plusNode == null || numberRightNode == null)
            {
                input.SetPosition(initialPos);
                return(null);
            }

            var exprTreeNode = new SyntaxTreeNode();

            plusNode.AddChildNode(numberLeftNode);
            plusNode.AddChildNode(numberRightNode);

            exprTreeNode.AddChildNode(plusNode);

            return(exprTreeNode);
        }
Пример #7
0
        /// <summary>
        /// Executa a análise sintática.
        /// </summary>
        /// <param name="input">Sequência de tokens de entrada</param>
        /// <returns>Árvore sintática abstrata</returns>
        /// <exception cref="SyntaxAnalysisException">Se houver algum erro durante a análise</exception>
        /// <exception cref="TheNodeWasNotCreatedException">Se algum nó não puder ser construído</exception>
        /// <exception cref="InputNotConsumedCompletelyException">Se a entrada não for completamente consumida</exception>
        public MyAbstractSyntaxTree Run(ObjectStream <MyToken> input)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            MyDiscardDelegate <MyToken> discarder = (c) => false;

            if (_grammar.OnParserDiscard != null)
            {
                discarder = _grammar.OnParserDiscard;
            }

            try
            {
                SyntaxTreeNode rootNode = _grammar.RootElement.Make(input, discarder);

                if (rootNode == null)
                {
                    throw new TheNodeWasNotCreatedException();
                }

                // Ignorando qualquer código descartável que tenha restado
                input.Discard(discarder);

                if (!input.EndOfStream())
                {
                    throw new InputNotConsumedCompletelyException();
                }

                return(new MyAbstractSyntaxTree(rootNode));
            }
            catch (SyntaxAnalysisException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new SyntaxAnalysisException(ex);
            }
        }
Пример #8
0
        public void Discard(MyDiscardDelegate <T> ignore)
        {
            if (ignore == null)
            {
                return;
            }

            while (!EndOfStream())
            {
                long pos     = GetPosition();
                T    element = Next();

                if (!ignore(element))
                {
                    // Volta a posição ao que era antes de obter o próximo elemento
                    SetPosition(pos);
                    break;
                }
            }
        }
Пример #9
0
        public override MyToken[] Eval(ObjectStream <Char> input, MyDiscardDelegate <char> discarder)
        {
            Ensure(input, discarder);

            // Ignora código descartável inicialmente
            input.Discard(discarder);

            var initialPos = input.GetPosition();
            var foundChars = new List <Char>();

            while (!input.EndOfStream())
            {
                var  pos = input.GetPosition();
                char c   = input.Next();

                if (!_validChars.Contains(c))
                {
                    input.SetPosition(pos);
                    break;
                }

                foundChars.Add(c);
            }

            if (!foundChars.Any())
            {
                input.SetPosition(initialPos);

                return(null);
            }

            var token = new MyToken(
                GetTokenClass(),
                initialPos,
                input.GetPosition(),
                new string(foundChars.ToArray())
                );

            return(new MyToken[] { token });
        }
Пример #10
0
        public override SyntaxTreeNode Make(ObjectStream <MyToken> input, MyDiscardDelegate <MyToken> discarder)
        {
            Ensure(input, discarder);

            // Ignora código descartável inicialmente
            input.Discard(discarder);

            if (input.EndOfStream())
            {
                return(null);
            }

            var initialPos = input.GetPosition();
            var token      = input.Next();

            if (token == null || (CalcTwoNumbersTokenClass)token.Class != (CalcTwoNumbersTokenClass)GetTokenClass())
            {
                input.SetPosition(initialPos);
                return(null);
            }

            return(new SumOperatorTreeNode());
        }
Пример #11
0
        public override MyToken[] Eval(ObjectStream <Char> input, MyDiscardDelegate <char> discarder)
        {
            Ensure(input, discarder);

            // Ignora código descartável inicialmente
            input.Discard(discarder);

            if (input.EndOfStream())
            {
                return(null);
            }

            var initialPos  = input.GetPosition();
            var foundTokens = new List <MyToken>();

            foreach (var element in _elements)
            {
                var elementTokens = element.Eval(input, discarder);

                // O primeiro elemento que obter sucesso, esse é o aceito
                if (elementTokens != null)
                {
                    foundTokens.AddRange(elementTokens);
                    break;
                }
            }

            if (!foundTokens.Any())
            {
                input.SetPosition(initialPos);

                return(null);
            }

            return(foundTokens.ToArray());
        }
Пример #12
0
 public abstract SyntaxTreeNode Make(ObjectStream <MyToken> input, MyDiscardDelegate <MyToken> discarder);
Пример #13
0
 public abstract MyToken[] Eval(ObjectStream <Char> input, MyDiscardDelegate <Char> discarder);
Пример #14
0
 public override SyntaxTreeNode Make(ObjectStream <MyToken> input, MyDiscardDelegate <MyToken> discarder)
 {
     throw new NotImplementedException();
 }