/// <summary> /// Visits the next intra-namespace declration. /// </summary> /// <param name="node">Node</param> private void VisitNextIntraNamespaceDeclaration(NamespaceDeclaration node) { if (base.TokenStream.Done) { throw new ParsingException("Expected \"}\".", new List<TokenType> { TokenType.Internal, TokenType.Public, TokenType.Partial, TokenType.Abstract, TokenType.Virtual, TokenType.EventDecl, TokenType.MachineDecl, TokenType.Monitor, TokenType.LeftSquareBracket, TokenType.RightCurlyBracket }); } bool fixpoint = false; var token = base.TokenStream.Peek(); switch (token.Type) { case TokenType.WhiteSpace: case TokenType.Comment: case TokenType.NewLine: base.TokenStream.Index++; break; case TokenType.CommentLine: case TokenType.Region: base.TokenStream.SkipWhiteSpaceAndCommentTokens(); break; case TokenType.CommentStart: base.TokenStream.SkipWhiteSpaceAndCommentTokens(); break; case TokenType.EventDecl: case TokenType.MachineDecl: case TokenType.Monitor: case TokenType.Internal: case TokenType.Public: case TokenType.Partial: case TokenType.Abstract: case TokenType.Virtual: this.VisitEventOrMachineDeclaration(node); base.TokenStream.Index++; break; case TokenType.LeftSquareBracket: base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); new AttributeListVisitor(base.TokenStream).Visit(); base.TokenStream.Index++; break; case TokenType.RightCurlyBracket: node.RightCurlyBracketToken = base.TokenStream.Peek(); fixpoint = true; base.TokenStream.Index++; break; case TokenType.Private: case TokenType.Protected: throw new ParsingException("Event and machine declarations must be internal or public.", new List<TokenType>()); default: throw new ParsingException("Unexpected token.", new List<TokenType>()); } if (!fixpoint) { this.VisitNextIntraNamespaceDeclaration(node); } }
/// <summary> /// Visits the syntax node. /// </summary> /// <param name="program">Program</param> /// <param name="parentNode">Node</param> /// <param name="isMonitor">Is a monitor</param> /// <param name="isPartial">Is partial</param> /// <param name="accMod">Access modifier</param> /// <param name="inhMod">Inheritance modifier</param> internal void Visit(IPSharpProgram program, NamespaceDeclaration parentNode, bool isMonitor, bool isPartial, AccessModifier accMod, InheritanceModifier inhMod) { var node = new MachineDeclaration(base.TokenStream.Program, parentNode, isMonitor, isPartial); node.AccessModifier = accMod; node.InheritanceModifier = inhMod; node.MachineKeyword = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Identifier) { throw new ParsingException("Expected machine identifier.", new List<TokenType> { TokenType.Identifier }); } base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit, TokenType.MachineIdentifier)); node.Identifier = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Program is PSharpProgram) { if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.Colon && base.TokenStream.Peek().Type != TokenType.LeftCurlyBracket)) { throw new ParsingException("Expected \":\" or \"{\".", new List<TokenType> { TokenType.Colon, TokenType.LeftCurlyBracket }); } if (base.TokenStream.Peek().Type == TokenType.Colon) { node.ColonToken = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Identifier) { throw new ParsingException("Expected base machine identifier.", new List<TokenType> { TokenType.Identifier }); } while (!base.TokenStream.Done && base.TokenStream.Peek().Type != TokenType.LeftCurlyBracket) { if (base.TokenStream.Peek().Type != TokenType.Identifier && base.TokenStream.Peek().Type != TokenType.Dot && base.TokenStream.Peek().Type != TokenType.NewLine) { throw new ParsingException("Expected base machine identifier.", new List<TokenType> { TokenType.Identifier, TokenType.Dot }); } else { node.BaseNameTokens.Add(base.TokenStream.Peek()); } base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); } } } if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.LeftCurlyBracket) { throw new ParsingException("Expected \"{\".", new List<TokenType> { TokenType.LeftCurlyBracket }); } base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit, TokenType.MachineLeftCurlyBracket)); node.LeftCurlyBracketToken = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); this.VisitNextPSharpIntraMachineDeclaration(node); parentNode.MachineDeclarations.Add(node); var stateDeclarations = node.GetAllStateDeclarations(); if (stateDeclarations.Count == 0 && node.BaseNameTokens.Count == 0) { throw new ParsingException("A machine must declare at least one state.", new List<TokenType>()); } var startStates = stateDeclarations.FindAll(s => s.IsStart); if (startStates.Count == 0 && node.BaseNameTokens.Count == 0) { throw new ParsingException("A machine must declare a start state.", new List<TokenType>()); } else if (startStates.Count > 1) { throw new ParsingException("A machine can declare only a single start state.", new List<TokenType>()); } }
/// <summary> /// Visits a namespace declaration. /// </summary> private void VisitNamespaceDeclaration() { var node = new NamespaceDeclaration(base.TokenStream.Program); node.NamespaceKeyword = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Identifier) { throw new ParsingException("Expected namespace identifier.", new List<TokenType> { TokenType.Identifier }); } while (!base.TokenStream.Done && base.TokenStream.Peek().Type != TokenType.LeftCurlyBracket) { if (base.TokenStream.Peek().Type != TokenType.Identifier && base.TokenStream.Peek().Type != TokenType.Dot && base.TokenStream.Peek().Type != TokenType.NewLine) { throw new ParsingException("Expected namespace identifier.", new List<TokenType> { TokenType.Identifier, TokenType.Dot }); } else { node.IdentifierTokens.Add(base.TokenStream.Peek()); } base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); } if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.LeftCurlyBracket) { throw new ParsingException("Expected \"{\".", new List<TokenType> { TokenType.LeftCurlyBracket }); } node.LeftCurlyBracketToken = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); this.VisitNextIntraNamespaceDeclaration(node); (this.Program as PSharpProgram).NamespaceDeclarations.Add(node); }
/// <summary> /// Visits an event or machine declaration. /// </summary> /// <param name="parentNode">Node</param> private void VisitEventOrMachineDeclaration(NamespaceDeclaration parentNode) { AccessModifier am = AccessModifier.None; InheritanceModifier im = InheritanceModifier.None; bool isPartial = false; while (!base.TokenStream.Done && base.TokenStream.Peek().Type != TokenType.EventDecl && base.TokenStream.Peek().Type != TokenType.MachineDecl && base.TokenStream.Peek().Type != TokenType.Monitor) { if (am != AccessModifier.None && (base.TokenStream.Peek().Type == TokenType.Public || base.TokenStream.Peek().Type == TokenType.Private || base.TokenStream.Peek().Type == TokenType.Protected || base.TokenStream.Peek().Type == TokenType.Internal)) { throw new ParsingException("More than one protection modifier.", new List<TokenType>()); } else if (im != InheritanceModifier.None && base.TokenStream.Peek().Type == TokenType.Abstract) { throw new ParsingException("Duplicate abstract modifier.", new List<TokenType>()); } else if (isPartial && base.TokenStream.Peek().Type == TokenType.Partial) { throw new ParsingException("Duplicate partial modifier.", new List<TokenType>()); } if (base.TokenStream.Peek().Type == TokenType.Public) { am = AccessModifier.Public; } else if (base.TokenStream.Peek().Type == TokenType.Private) { am = AccessModifier.Private; } else if (base.TokenStream.Peek().Type == TokenType.Protected) { am = AccessModifier.Protected; } else if (base.TokenStream.Peek().Type == TokenType.Internal) { am = AccessModifier.Internal; } else if (base.TokenStream.Peek().Type == TokenType.Abstract) { im = InheritanceModifier.Abstract; } else if (base.TokenStream.Peek().Type == TokenType.Partial) { isPartial = true; } base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); } if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.EventDecl && base.TokenStream.Peek().Type != TokenType.MachineDecl && base.TokenStream.Peek().Type != TokenType.Monitor)) { throw new ParsingException("Expected event, machine or monitor declaration.", new List<TokenType> { TokenType.EventDecl, TokenType.MachineDecl, TokenType.Monitor }); } if (base.TokenStream.Peek().Type == TokenType.EventDecl) { if (am == AccessModifier.Private) { throw new ParsingException("An event cannot be private.", new List<TokenType>()); } else if (am == AccessModifier.Protected) { throw new ParsingException("An event cannot be protected.", new List<TokenType>()); } if (im == InheritanceModifier.Abstract) { throw new ParsingException("An event cannot be abstract.", new List<TokenType>()); } if (isPartial) { throw new ParsingException("An event cannot be declared as partial.", new List<TokenType>()); } new EventDeclarationVisitor(base.TokenStream).Visit(null, parentNode, am); } else if (base.TokenStream.Peek().Type == TokenType.MachineDecl) { if (am == AccessModifier.Private) { throw new ParsingException("A machine cannot be private.", new List<TokenType>()); } else if (am == AccessModifier.Protected) { throw new ParsingException("A machine cannot be protected.", new List<TokenType>()); } new MachineDeclarationVisitor(base.TokenStream).Visit(null, parentNode, false, isPartial, am, im); } else if (base.TokenStream.Peek().Type == TokenType.Monitor) { if (am == AccessModifier.Private) { throw new ParsingException("A monitor cannot be private.", new List<TokenType>()); } else if (am == AccessModifier.Protected) { throw new ParsingException("A monitor cannot be protected.", new List<TokenType>()); } new MachineDeclarationVisitor(base.TokenStream).Visit(null, parentNode, true, isPartial, am, im); } }
/// <summary> /// Visits the syntax node. /// </summary> /// <param name="program">Program</param> /// <param name="parentNode">Node</param> /// <param name="accMod">Access modifier</param> internal void Visit(IPSharpProgram program, NamespaceDeclaration parentNode, AccessModifier accMod) { var node = new EventDeclaration(base.TokenStream.Program); node.AccessModifier = accMod; node.EventKeyword = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.Identifier && base.TokenStream.Peek().Type != TokenType.HaltEvent && base.TokenStream.Peek().Type != TokenType.DefaultEvent)) { throw new ParsingException("Expected event identifier.", new List<TokenType> { TokenType.Identifier, TokenType.HaltEvent, TokenType.DefaultEvent }); } if (base.TokenStream.Peek().Type == TokenType.Identifier) { base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit, TokenType.EventIdentifier)); } node.Identifier = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.Assert && base.TokenStream.Peek().Type != TokenType.Assume && base.TokenStream.Peek().Type != TokenType.Colon && base.TokenStream.Peek().Type != TokenType.Semicolon)) { throw new ParsingException("Expected \":\" or \";\".", new List<TokenType> { TokenType.Assert, TokenType.Assume, TokenType.Colon, TokenType.Semicolon }); } if (base.TokenStream.Peek().Type == TokenType.Assert || base.TokenStream.Peek().Type == TokenType.Assume) { bool isAssert = true; if (base.TokenStream.Peek().Type == TokenType.Assert) { node.AssertKeyword = base.TokenStream.Peek(); } else { node.AssumeKeyword = base.TokenStream.Peek(); isAssert = false; } base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Identifier) { throw new ParsingException("Expected integer.", new List<TokenType> { TokenType.Identifier }); } int value; if (!int.TryParse(base.TokenStream.Peek().TextUnit.Text, out value)) { throw new ParsingException("Expected integer.", new List<TokenType> { TokenType.Identifier }); } if (isAssert) { node.AssertValue = value; } else { node.AssumeValue = value; } base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.Colon && base.TokenStream.Peek().Type != TokenType.Semicolon)) { throw new ParsingException("Expected \":\" or \";\".", new List<TokenType> { TokenType.Colon, TokenType.Semicolon }); } } if (base.TokenStream.Peek().Type == TokenType.Colon) { node.ColonToken = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); PBaseType payloadType = null; new TypeIdentifierVisitor(base.TokenStream).Visit(ref payloadType); node.PayloadType = payloadType; } if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Semicolon) { throw new ParsingException("Expected \";\".", new List<TokenType> { TokenType.Semicolon }); } node.SemicolonToken = base.TokenStream.Peek(); parentNode.EventDeclarations.Add(node); }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="namespaceNode">NamespaceDeclaration</param> /// <param name="isMonitor">Is a monitor</param> /// <param name="isPartial">Is partial</param> internal MachineDeclaration(IPSharpProgram program, NamespaceDeclaration namespaceNode, bool isMonitor, bool isPartial) : base(program) { this.Namespace = namespaceNode; this.IsMonitor = isMonitor; this.IsPartial = isPartial; this.BaseNameTokens = new List<Token>(); this.FieldDeclarations = new List<FieldDeclaration>(); this.StateDeclarations = new List<StateDeclaration>(); this.StateGroupDeclarations = new List<StateGroupDeclaration>(); this.MethodDeclarations = new List<MethodDeclaration>(); this.RewrittenMethods = new HashSet<QualifiedMethod>(); }
/// <summary> /// Visits the syntax node. /// </summary> /// <param name="program">Program</param> /// <param name="parentNode">Node</param> /// <param name="accMod">Access modifier</param> internal void Visit(IPSharpProgram program, NamespaceDeclaration parentNode, AccessModifier accMod) { var node = new EventDeclaration(base.TokenStream.Program); node.AccessModifier = accMod; node.EventKeyword = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.Identifier && base.TokenStream.Peek().Type != TokenType.HaltEvent && base.TokenStream.Peek().Type != TokenType.DefaultEvent)) { throw new ParsingException("Expected event identifier.", new List<TokenType> { TokenType.Identifier, TokenType.HaltEvent, TokenType.DefaultEvent }); } if (base.TokenStream.Peek().Type == TokenType.Identifier) { base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit, TokenType.EventIdentifier)); } node.Identifier = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.Assert && base.TokenStream.Peek().Type != TokenType.Assume && base.TokenStream.Peek().Type != TokenType.LeftAngleBracket && base.TokenStream.Peek().Type != TokenType.LeftParenthesis && base.TokenStream.Peek().Type != TokenType.Semicolon)) { throw new ParsingException("Expected \"(\" or \";\".", new List<TokenType> { TokenType.Assert, TokenType.Assume, TokenType.LeftParenthesis, TokenType.Semicolon }); } int genericCount = 0; while (!base.TokenStream.Done && base.TokenStream.Peek().Type != TokenType.Assert && base.TokenStream.Peek().Type != TokenType.Assume && base.TokenStream.Peek().Type != TokenType.LeftParenthesis && base.TokenStream.Peek().Type != TokenType.Semicolon) { if (base.TokenStream.Peek().Type != TokenType.Identifier && base.TokenStream.Peek().Type != TokenType.Dot && base.TokenStream.Peek().Type != TokenType.Comma && base.TokenStream.Peek().Type != TokenType.LeftAngleBracket && base.TokenStream.Peek().Type != TokenType.RightAngleBracket && base.TokenStream.Peek().Type != TokenType.Object && base.TokenStream.Peek().Type != TokenType.String && base.TokenStream.Peek().Type != TokenType.Sbyte && base.TokenStream.Peek().Type != TokenType.Byte && base.TokenStream.Peek().Type != TokenType.Short && base.TokenStream.Peek().Type != TokenType.Ushort && base.TokenStream.Peek().Type != TokenType.Int && base.TokenStream.Peek().Type != TokenType.Uint && base.TokenStream.Peek().Type != TokenType.Long && base.TokenStream.Peek().Type != TokenType.Ulong && base.TokenStream.Peek().Type != TokenType.Char && base.TokenStream.Peek().Type != TokenType.Bool && base.TokenStream.Peek().Type != TokenType.Decimal && base.TokenStream.Peek().Type != TokenType.Float && base.TokenStream.Peek().Type != TokenType.Double) { break; } if (genericCount == 0 && base.TokenStream.Peek().Type == TokenType.Comma) { throw new ParsingException("Expected generic type.", new List<TokenType> { TokenType.Identifier }); } else if (base.TokenStream.Peek().Type == TokenType.LeftAngleBracket) { node.GenericType.Add(base.TokenStream.Peek()); genericCount++; } else if (base.TokenStream.Peek().Type == TokenType.RightAngleBracket) { if (genericCount == 0) { throw new ParsingException("Invalid generic expression.", new List<TokenType> { TokenType.Identifier }); } node.GenericType.Add(base.TokenStream.Peek()); genericCount--; } else if (base.TokenStream.Peek().Type == TokenType.Identifier) { base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit, TokenType.EventIdentifier)); node.GenericType.Add(base.TokenStream.Peek()); } else if (base.TokenStream.Peek().Type == TokenType.Dot || base.TokenStream.Peek().Type == TokenType.Comma || base.TokenStream.Peek().Type == TokenType.Object || base.TokenStream.Peek().Type == TokenType.String || base.TokenStream.Peek().Type == TokenType.Sbyte || base.TokenStream.Peek().Type == TokenType.Byte || base.TokenStream.Peek().Type == TokenType.Short || base.TokenStream.Peek().Type == TokenType.Ushort || base.TokenStream.Peek().Type == TokenType.Int || base.TokenStream.Peek().Type == TokenType.Uint || base.TokenStream.Peek().Type == TokenType.Long || base.TokenStream.Peek().Type == TokenType.Ulong || base.TokenStream.Peek().Type == TokenType.Char || base.TokenStream.Peek().Type == TokenType.Bool || base.TokenStream.Peek().Type == TokenType.Decimal || base.TokenStream.Peek().Type == TokenType.Float || base.TokenStream.Peek().Type == TokenType.Double) { node.GenericType.Add(base.TokenStream.Peek()); } base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); } if (genericCount > 0) { throw new ParsingException("Invalid generic expression.", new List<TokenType> { TokenType.Identifier }); } if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.Assert && base.TokenStream.Peek().Type != TokenType.Assume && base.TokenStream.Peek().Type != TokenType.LeftParenthesis && base.TokenStream.Peek().Type != TokenType.Semicolon)) { throw new ParsingException("Expected \"(\" or \";\".", new List<TokenType> { TokenType.Assert, TokenType.Assume, TokenType.LeftParenthesis, TokenType.Semicolon }); } if (base.TokenStream.Peek().Type == TokenType.Assert || base.TokenStream.Peek().Type == TokenType.Assume) { bool isAssert = true; if (base.TokenStream.Peek().Type == TokenType.Assert) { node.AssertKeyword = base.TokenStream.Peek(); } else { node.AssumeKeyword = base.TokenStream.Peek(); isAssert = false; } base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Identifier) { throw new ParsingException("Expected integer.", new List<TokenType> { TokenType.Identifier }); } int value; if (!int.TryParse(base.TokenStream.Peek().TextUnit.Text, out value)) { throw new ParsingException("Expected integer.", new List<TokenType> { TokenType.Identifier }); } if (isAssert) { node.AssertValue = value; } else { node.AssumeValue = value; } base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.LeftParenthesis && base.TokenStream.Peek().Type != TokenType.Semicolon)) { throw new ParsingException("Expected \"(\" or \";\".", new List<TokenType> { TokenType.LeftParenthesis, TokenType.Semicolon }); } } if (base.TokenStream.Peek().Type == TokenType.LeftParenthesis) { node.LeftParenthesis = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); bool isType = false; while (!base.TokenStream.Done && base.TokenStream.Peek().Type != TokenType.RightParenthesis) { if (isType && base.TokenStream.Peek().Type != TokenType.Colon && base.TokenStream.Peek().Type != TokenType.Comma) { TextUnit textUnit = null; new TypeIdentifierVisitor(base.TokenStream).Visit(ref textUnit); var typeIdentifier = new Token(textUnit, TokenType.TypeIdentifier); node.PayloadTypes.Add(typeIdentifier); } else if (base.TokenStream.Peek().Type != TokenType.Colon && base.TokenStream.Peek().Type != TokenType.Comma) { node.PayloadIdentifiers.Add(base.TokenStream.Peek()); isType = true; base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); } if (base.TokenStream.Peek().Type == TokenType.Comma) { isType = false; base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); } else if (base.TokenStream.Peek().Type == TokenType.Colon) { base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); } } if (node.PayloadIdentifiers.Count != node.PayloadTypes.Count) { throw new ParsingException("The payload type of event '" + node.Identifier.TextUnit.Text + "' was not declared correctly.\n" + " You must declare both a type and a name identifier, for example:\n\n" + " event e (a:int, b:bool)\n", new List<TokenType> { TokenType.RightParenthesis }); } if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.RightParenthesis) { throw new ParsingException("Expected \")\".", new List<TokenType> { TokenType.RightParenthesis }); } node.RightParenthesis = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); } if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Semicolon) { throw new ParsingException("Expected \";\".", new List<TokenType> { TokenType.Semicolon }); } node.SemicolonToken = base.TokenStream.Peek(); parentNode.EventDeclarations.Add(node); }