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); }
public Node Analyse(ITokenizer tokenizer) { _tokenizer = tokenizer; if (_tokenizer.CurrentToken == TokenType.None) { _tokenizer.GetNextToken(); } return(HandleSuperExpression()); }
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)); }