/// <summary> /// Visits the syntax node. /// </summary> /// <param name="program">Program</param> /// <param name="parentNode">Node</param> /// <param name="isMain">Is main machine</param> /// <param name="isModel">Is a model</param> /// <param name="isMonitor">Is a monitor</param> /// <param name="accMod">Access modifier</param> /// <param name="inhMod">Inheritance modifier</param> internal void Visit(IPSharpProgram program, NamespaceDeclaration parentNode, bool isMain, bool isModel, bool isMonitor, AccessModifier accMod, InheritanceModifier inhMod) { var node = new MachineDeclaration(base.TokenStream.Program, isMain, isModel, isMonitor); 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.CurrentMachine = base.TokenStream.Peek().Text; 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(); if (base.TokenStream.Program is PSharpProgram) { this.VisitNextPSharpIntraMachineDeclaration(node); parentNode.MachineDeclarations.Add(node); } else { this.VisitNextPIntraMachineDeclaration(node); (program as PProgram).MachineDeclarations.Add(node); } if (node.StateDeclarations.Count == 0 && node.BaseNameTokens.Count == 0) { throw new ParsingException("A machine must declare at least one state.", new List<TokenType>()); } var initialStates = node.StateDeclarations.FindAll(s => s.IsInitial); if (initialStates.Count == 0 && node.BaseNameTokens.Count == 0) { throw new ParsingException("A machine must declare a start state.", new List<TokenType>()); } else if (initialStates.Count > 1) { throw new ParsingException("A machine can declare only a single start state.", new List<TokenType>()); } }
/// <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(); if (base.TokenStream.Program is PSharpProgram) { parentNode.EventDeclarations.Add(node); } else { (program as PProgram).EventDeclarations.Add(node); } }
/// <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 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.Abstract, TokenType.Virtual, TokenType.EventDecl, TokenType.MachineDecl, TokenType.ModelDecl, 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.ModelDecl: case TokenType.Monitor: case TokenType.Internal: case TokenType.Public: 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 an event or machine declaration. /// </summary> /// <param name="parentNode">Node</param> private void VisitEventOrMachineDeclaration(NamespaceDeclaration parentNode) { AccessModifier am = AccessModifier.None; InheritanceModifier im = InheritanceModifier.None; while (!base.TokenStream.Done && base.TokenStream.Peek().Type != TokenType.EventDecl && base.TokenStream.Peek().Type != TokenType.MachineDecl && base.TokenStream.Peek().Type != TokenType.ModelDecl && 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>()); } 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; } 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.ModelDecl && base.TokenStream.Peek().Type != TokenType.Monitor)) { throw new ParsingException("Expected event, machine, model or monitor declaration.", new List<TokenType> { TokenType.EventDecl, TokenType.MachineDecl, TokenType.ModelDecl, 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>()); } new EventDeclarationVisitor(base.TokenStream).Visit(null, parentNode, am); } else if (base.TokenStream.Peek().Type == TokenType.MachineDecl || base.TokenStream.Peek().Type == TokenType.ModelDecl) { 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>()); } if (base.TokenStream.Peek().Type == TokenType.MachineDecl) { new MachineDeclarationVisitor(base.TokenStream).Visit(null, parentNode, false, false, false, am, im); } else if (base.TokenStream.Peek().Type == TokenType.ModelDecl) { new MachineDeclarationVisitor(base.TokenStream).Visit(null, parentNode, false, true, false, 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, false, false, true, am, im); } }