private ThreadSpec HandleThread() { var thread = new ThreadSpec { BeginPosition = ThisToken().TokenBeginIdx }; TryParseAndResumeToToken(() => { ConsumeType(TokenTypes.Thread); thread.Identifier = ConsumeType(TokenTypes.Identifier); var resumableType = new[] { TokenTypes.Features, TokenTypes.Flows, TokenTypes.Properties, TokenTypes.End, }; TryParseAndResumeToToken(() => thread.Features = HandleFeatures(), resumableType); TryParseAndResumeToToken(() => thread.Flows = HandleFlows(), resumableType); TryParseAndResumeToToken(() => thread.Properties = HandleProperties(), resumableType); ConsumeType(TokenTypes.End); var token = ThisToken(); EnsureToken(token, TokenTypes.Identifier); if (token.Lexeme != thread.Identifier.Lexeme) { throw Error(new SemanticException("The Identifier in Thread must be matched.", token, thread)); } Consume(); }, TokenTypes.Semicolon); var endToken = ConsumeType(TokenTypes.Semicolon); thread.EndPosition = endToken.TokenEndIdx; return(thread); }
private (Application, ICollection <ParseException>) DoParse() { var application = new Application { BeginPosition = _tokens.First().TokenBeginIdx, EndPosition = _tokens.Last().TokenEndIdx, Threads = _parsed }; try { while (HaveNextToken()) { ThreadSpec thread = null; TryParseAndResumeToToken(() => { thread = HandleThread(); }, TokenTypes.Thread); _parsed.AddLast(thread); } } catch (NotEnoughTokenException) { } return(application, _exceptions); }