private static Syntax ParseVector(Token thisToken, Tokenizer moreTokens) { var listContents = new ListSyntax( ); Token dotToken = null; var nextToken = moreTokens.ReadToken(); while (nextToken != null && nextToken.type != TokenType.CloseBracket) { // Parse this token listContents.Add(ParseToken(nextToken, moreTokens)); // Fetch the next token nextToken = moreTokens.ReadToken(); if (nextToken == null) { throw ParserError.SyntaxError("parser", "Improperly formed list.", dotToken); } //if (!improper && nextToken.Type == TokenType.Symbol && dotSymbol.Equals(nextToken.Value) && thisToken.Type == TokenType.OpenBracket) if (nextToken.type == TokenType.Dot) { throw ParserError.SyntaxError("parser", "Improperly formed dotted list", nextToken); } } if (nextToken == null) // Missing ')' { throw ParserError.SyntaxError("parser", "Missing close parenthesis", thisToken); } return(Syntax.Create(listContents, thisToken.location)); }
/// <summary> /// Turns thisToken into an object, using moreTokens to get further tokens if required /// </summary> /// <returns></returns> private static Syntax ParseToken(Token thisToken, Tokenizer moreTokens) { if (thisToken == null) { throw ParserError.SyntaxError("parser", "unexpectedly reached the end of the input", moreTokens.LastToken); } switch (thisToken.type) { //case TokenType.Dot: // return thisToken; //TODO maybe exception or symbol . case TokenType.Character: return(Syntax.Create(thisToken.GetCharacter(), thisToken.location)); case TokenType.Boolean: return(Syntax.Create(thisToken.GetBool(), thisToken.location)); case TokenType.String: return(Syntax.Create(thisToken.GetString(), thisToken.location)); case TokenType.Symbol: return(Syntax.Create(thisToken.GetName(), thisToken.location)); case TokenType.Heximal: case TokenType.Integer: return(Syntax.Create(thisToken.GetInteger(), thisToken.location)); case TokenType.Floating: return(Syntax.Create(thisToken.GetFloat(), thisToken.location)); case TokenType.OpenBracket: return(ParseList(thisToken, moreTokens)); case TokenType.OpenVector: return(ParseVector(thisToken, moreTokens)); case TokenType.Quote: case TokenType.Unquote: case TokenType.UnquoteSplicing: case TokenType.QuasiQuote: return(ParseQuoted(thisToken, moreTokens)); case TokenType.BadNumber: throw ParserError.SyntaxError("parser", "looks like it should be a number, but it contains a syntax error", thisToken); default: // Unknown token type throw ParserError.SyntaxError("parser", "the element is being used in a context where it is not understood", thisToken); } }
/// <summary> /// Parses a scheme expression in the default manner /// </summary> /// <returns>A scheme object</returns> /// <remarks>It is an error to pass scheme to this method with 'extraneous' tokens, such as trailing closing brackets</remarks> public static Syntax Parse(string scheme, string filepath) { var reader = new Tokenizer(new System.IO.StringReader(scheme), filepath); var res = Parse(reader); var token = reader.ReadToken(); if (token != null) { throw ParserError.SyntaxError("parser", "found extra tokens after the end of a scheme expression", token); } return(res); }
private static Syntax ParseList(Token thisToken, Tokenizer moreTokens) { // Is a list/vector var listContents = new LinkedList <Syntax> ( ); Token dotToken = null; var nextToken = moreTokens.ReadToken(); while (nextToken != null && nextToken.type != TokenType.CloseBracket) { // Parse this token listContents.AddLast(ParseToken(nextToken, moreTokens)); // Fetch the next token nextToken = moreTokens.ReadToken(); if (nextToken == null) { throw ParserError.SyntaxError("parser", "Improperly formed list.", dotToken); } if (nextToken.type == TokenType.Dot) { if (dotToken != null || thisToken.type != TokenType.OpenBracket) { throw ParserError.SyntaxError("parser", "Improperly formed dotted list", nextToken); } dotToken = nextToken; nextToken = moreTokens.ReadToken(); if (nextToken == null) { throw ParserError.SyntaxError("parser", "Improperly formed dotted list", dotToken); } if (nextToken.type == TokenType.CloseBracket) { throw ParserError.SyntaxError("parser", "Improperly formed dotted list", dotToken); } listContents.AddLast(ParseToken(nextToken, moreTokens)); nextToken = moreTokens.ReadToken(); if (nextToken.type != TokenType.CloseBracket) { throw ParserError.SyntaxError("parser", "Improperly formed dotted list", dotToken); } break; } } if (nextToken == null) { // Missing ')' throw ParserError.SyntaxError("parser", "missing close parenthesis", thisToken); } if (dotToken != null) { if (listContents.Count == 2) { return(Syntax.Create(new Pair(listContents[0], listContents[1]), thisToken.location)); } else { throw ParserError.SyntaxError("parser", "improper dot syntax", thisToken); } } else { return(Syntax.Create(listContents, thisToken.location)); } }