void RequireTokenType(Token.Types type) { if (!this.TokenIs (type)) { this.RequireTokenError ( new Token.Types?[] { type }, new string[] { }, this.CurrentToken ()); } }
bool TokenIs(Token.Types type, string content = null) { if (!Finished ()) { var token = this.CurrentToken (); return token.Type == type && (content == null || token.Content == content); } else { return false; } }
void RequireTokenExactly(Token.Types type, string content) { if (!this.TokenIs (type, content)) { this.RequireTokenError ( new Token.Types?[] { type }, new string[] { content }, this.CurrentToken ()); } }
void RequireTokenError( IEnumerable<Token.Types?> types, IEnumerable<string> contents, Token actualToken) { var possibleTypes = types.Where (type => type != null); var possibleContents = contents.Where (content => content != null); string expectation = ""; if (possibleContents.Count () == 0) { if (possibleTypes.Count () == 0) { Utils.Panic (); } else if (possibleTypes.Count () == 1) { expectation = String.Format ("Expected a {0}", possibleTypes.First ().ToString ().ToLower ()); } else { expectation = String.Format ( "Expected one of {0}", String.Join (", ", possibleTypes.Select (type => type.ToString ().ToLower ()))); } } else if (possibleContents.Count () == 1) { expectation = String.Format ("Expected '{0}'", possibleContents.First ()); } else { expectation = String.Format ( "Expected one of {0}", String.Join (", ", possibleContents.Select (content => "'" + content + "'"))); } string actualInput; if (actualToken != null) { actualInput = String.Format ("but got '{0}'", actualToken.Content); } else { actualInput = "but reached the end of input"; } var message = String.Format ("{0}, {1}.", expectation, actualInput); this.RaiseError (message); }
void NextToken() { this.lastToken = this.CurrentToken (); this.tokenIndex++; }
void ConsumeToken(Token.Types type, string content) { this.RequireTokenExactly (type, content); this.NextToken (); }
Token TokenizePred(Token.Types type, Func<char, bool> pred) { int startPos = this.pos; while (!this.Finished() && pred(this.CurrentChar())) { this.NextChar(); } return new Token() { StartPos = startPos, EndPos = this.pos - 1, Type = type, Content = this.source.Content.Substring(startPos, this.pos - startPos) }; }