예제 #1
0
        private Node HandleExpression()
        {
            var left = HandleTerm();

            while (_tokenizer.CurrentToken == TokenType.Plus || _tokenizer.CurrentToken == TokenType.Minus)
            {
                var type = _tokenizer.CurrentToken;
                _tokenizer.GetNextToken();
                left = new BinaryNode(type, left, HandleTerm());
            }
            return(left);
        }
예제 #2
0
 public Node Analyse(ITokenizer tokenizer)
 {
     _tokenizer = tokenizer;
     if (_tokenizer.CurrentToken == TokenType.None)
     {
         _tokenizer.GetNextToken();
     }
     return(HandleSuperExpression());
 }
예제 #3
0
        private ParseBlock ParseBlock()
        {
            var            parameters      = new List <CommandParameter>();
            var            block           = new StringBuilder();
            var            isEndOfLine     = false;
            var            isVariable      = false;
            var            isParameterName = false;
            var            blockStartCount = 0;
            SourceLocation locationStart   = null;

            while (!isEndOfLine)
            {
                var token = _tokenizer.GetNextToken();
                if (token != null)
                {
                    _lastTokenLocation = token.Location;
                }

                if (locationStart == null)
                {
                    locationStart = token?.Location;
                }

                if (token == null || (token is LiteralToken lt && lt.Value == '\n' && blockStartCount == 0))
                {
                    if (blockStartCount > 0)
                    {
                        throw new ParseException(_lastTokenLocation, Texts.MissingBlockEnd);
                    }
                    else if (blockStartCount < 0)
                    {
                        throw new ParseException(_lastTokenLocation, Texts.MissingBlockStart);
                    }

                    isEndOfLine = true;
                    break;
                }

                if (token is SpecialToken specialToken)
                {
                    switch (specialToken.Type)
                    {
                    case SpecialTokenType.BlockStart:
                        blockStartCount++;
                        break;

                    case SpecialTokenType.BlockEnd:
                        blockStartCount--;
                        if (blockStartCount == 0)
                        {
                            break;
                        }
                        break;

                    case SpecialTokenType.VariableMarker:
                        var blockValue = block.ToString();

                        if (isVariable)
                        {
                            isVariable = false;

                            if (!string.IsNullOrEmpty(blockValue))
                            {
                                parameters.Add(new VariableCommandParameter(blockValue));
                            }
                            else
                            {
                                throw new ParseException(token.Location, Texts.MissingVariableName);
                            }

                            block.Clear();
                        }
                        else
                        {
                            isVariable = true;

                            if (!string.IsNullOrEmpty(blockValue))
                            {
                                parameters.Add(new LiteralCommandParameter(blockValue));
                            }

                            block.Clear();
                        }
                        break;

                    case SpecialTokenType.ParameterName:
                        if (blockStartCount == 0 && block.Length == 0)
                        {
                            isParameterName = true;
                        }
                        else
                        {
                            block.Append("-");
                        }
                        break;

                    default:
                        throw new ParseException(specialToken.Location, string.Format(Texts.UnexpectedToken, specialToken.Type));
                    }
                }
                else if (token is LiteralToken literalToken)
                {
                    if (blockStartCount == 0 && char.IsWhiteSpace(literalToken.Value))
                    {
                        break;
                    }

                    block.Append(literalToken.Value);
                }
            }

            if (isVariable)
            {
                throw new ParseException(locationStart, Texts.UnpairedVariableToken);
            }

            var parsedBlock = block.ToString();

            if (isParameterName)
            {
                parameters.Add(new ParameterNameCommandParameter(block.ToString()));
            }
            else if (!string.IsNullOrEmpty(parsedBlock))
            {
                parameters.Add(new LiteralCommandParameter(block.ToString()));
            }

            var location = locationStart;

            if (location == null)
            {
                location = new SourceLocation(_lastTokenLocation.LineNumber, _lastTokenLocation.CharacterNumber + 1);
            }

            if (parameters.Count == 0)
            {
                return(new ParseBlock(location, null, isEndOfLine: isEndOfLine));
            }

            if (parameters.Count == 1)
            {
                return(new ParseBlock(location, parameters[0], isEndOfLine: isEndOfLine));
            }

            return(new ParseBlock(location, new AggregateCommandParameter(parameters), isEndOfLine: isEndOfLine));
        }