/// <summary> /// Parses a token stream creating the largest statement possible /// </summary> /// <param name="stream">Stream of tokens to parse</param> /// <returns>Statement</returns> private StatementList ParseStatement(Stream stream) { var previousToken = stream.Peek(); if (previousToken == null) { Errors.Add(new EndOfStreamException()); return(new StatementList()); } var tokenType = previousToken.Type; Token identifier = null; switch (tokenType) { case TokenType.Identifier: //standard identifier identifier = stream.Next(); break; case TokenType.OpenBracket: case TokenType.OpenParenthesis: //ignore these break; case TokenType.StringLiteral: case TokenType.StringLiteralPipe: case TokenType.QuotedStringLiteral: //string statement identifier = stream.Next(); break; case TokenType.At: stream.GetNextNoReturn(); identifier = stream.Next(); break; case TokenType.Equal: stream.GetNextNoReturn(); identifier = stream.Next(); break; default: Errors.Add(new UnexpectedToken(previousToken)); return(new StatementList()); //throw new ParserException(stream.Peek()); } Statement statement; StatementTail tail = null; while (stream.Peek() != null) { var token = stream.Peek(); if (token == null) { break; } switch (token.Type) { case TokenType.OpenParenthesis: case TokenType.OpenBracket: case TokenType.OpenBrace: tail = ParseStatementTail(stream); break; case TokenType.GreaterThan: //consume greater than stream.NextNoReturn(); //might be a single child or a statement list of siblings tail = ParseSingleStatementTail(stream, tail); break; case TokenType.StringLiteralPipe: if (previousToken is StringLiteralPipeToken) { //if the previous token was a string literal pipe then we don't continue processing goto default; } //this overrides all previous tail elements tail = ParseSingleStatementTail(stream, tail); break; default: GetStatementFromToken(identifier, tail); goto checkForSiblings; } } checkForSiblings: statement = GetStatementFromToken(identifier, tail, previousToken); var list = new StatementList(); list.Add(statement); while (stream.Peek() != null) { //Parrot.Debugger.Debug.WriteLine("Looking for siblings"); if (stream.Peek().Type == TokenType.Plus) { //it's now a statementlist not a statement stream.NextNoReturn(); var siblings = ParseStatement(stream); foreach (var sibling in siblings) { list.Add(sibling); } } else { break; } } return(list); }
/// <summary> /// Parses a token stream creating the largest statement possible /// </summary> /// <param name="stream">Stream of tokens to parse</param> /// <returns>Statement</returns> private StatementList ParseStatement(Stream stream) { var previousToken = stream.Peek(); if (previousToken == null) { Errors.Add(new EndOfStreamException()); return new StatementList(); } var tokenType = previousToken.Type; Token identifier = null; switch (tokenType) { case TokenType.Identifier: //standard identifier identifier = stream.Next(); break; case TokenType.OpenBracket: case TokenType.OpenParenthesis: //ignore these break; case TokenType.StringLiteral: case TokenType.StringLiteralPipe: case TokenType.QuotedStringLiteral: //string statement identifier = stream.Next(); break; case TokenType.At: stream.GetNextNoReturn(); identifier = stream.Next(); break; case TokenType.Equal: stream.GetNextNoReturn(); identifier = stream.Next(); break; default: Errors.Add(new UnexpectedToken(previousToken)); return new StatementList(); //throw new ParserException(stream.Peek()); } Statement statement; StatementTail tail = null; while (stream.Peek() != null) { var token = stream.Peek(); if (token == null) { break; } switch (token.Type) { case TokenType.OpenParenthesis: case TokenType.OpenBracket: case TokenType.OpenBrace: tail = ParseStatementTail(stream); break; case TokenType.GreaterThan: //consume greater than stream.NextNoReturn(); //might be a single child or a statement list of siblings tail = ParseSingleStatementTail(stream, tail); break; case TokenType.StringLiteralPipe: if (previousToken is StringLiteralPipeToken) { //if the previous token was a string literal pipe then we don't continue processing goto default; } //this overrides all previous tail elements tail = ParseSingleStatementTail(stream, tail); break; default: GetStatementFromToken(identifier, tail); goto checkForSiblings; } } checkForSiblings: statement = GetStatementFromToken(identifier, tail, previousToken); var list = new StatementList(); list.Add(statement); while (stream.Peek() != null) { //Parrot.Debugger.Debug.WriteLine("Looking for siblings"); if (stream.Peek().Type == TokenType.Plus) { //it's now a statementlist not a statement stream.NextNoReturn(); var siblings = ParseStatement(stream); foreach (var sibling in siblings) { list.Add(sibling); } } else { break; } } return list; }