/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">MachineDeclarationNode</param> /// <param name="stateNode">StateDeclarationNode</param> /// <param name="isModel">Is a model</param> internal BlockSyntax(IPSharpProgram program, MachineDeclaration machineNode, StateDeclaration stateNode, bool isModel) : base(program, isModel) { this.Machine = machineNode; this.State = stateNode; }
/// <summary> /// Initializes a new instance of the <see cref="BlockSyntax"/> class. /// </summary> internal BlockSyntax(IPSharpProgram program, MachineDeclaration machineNode, StateDeclaration stateNode) : base(program) { this.Machine = machineNode; this.State = stateNode; }
/// <summary> /// Visits the syntax node. /// </summary> /// <param name="parentNode">Node</param> /// <param name="isStart">Is start state</param> /// <param name="accMod">Access modifier</param> internal void Visit(MachineDeclaration parentNode, bool isStart, AccessModifier accMod) { var node = new StateDeclaration(base.TokenStream.Program, parentNode, isStart, parentNode.IsModel); node.AccessModifier = accMod; node.StateKeyword = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Identifier) { throw new ParsingException("Expected state identifier.", new List<TokenType> { TokenType.Identifier }); } base.TokenStream.CurrentState = base.TokenStream.Peek().Text; base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit, TokenType.StateIdentifier)); node.Identifier = 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.StateLeftCurlyBracket)); node.LeftCurlyBracketToken = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Program is PSharpProgram) { this.VisitNextPSharpIntraStateDeclaration(node); } else { this.VisitNextPIntraStateDeclaration(node); } parentNode.StateDeclarations.Add(node); }
/// <summary> /// Initializes a new instance of the <see cref="EventDeclaration"/> class. /// </summary> internal EventDeclaration(IPSharpProgram program, MachineDeclaration machineNode, ModifierSet modSet) : base(program) { this.Machine = machineNode; this.AccessModifier = modSet.AccessModifier; this.GenericType = new List <Token>(); this.PayloadTypes = new List <Token>(); this.PayloadIdentifiers = new List <Token>(); }
/// <summary> /// Visits the syntax node. /// </summary> /// <param name="parentNode">Node</param> /// <param name="typeIdentifier">Type identifier</param> /// <param name="identifier">Identifier</param> /// <param name="accMod">Access modifier</param> /// <param name="inhMod">Inheritance modifier</param> /// <param name="isAsync">Is async</param> /// <param name="isPartial">Is partial</param> internal void Visit(MachineDeclaration parentNode, Token typeIdentifier, Token identifier, AccessModifier accMod, InheritanceModifier inhMod, bool isAsync, bool isPartial) { var node = new MethodDeclaration(base.TokenStream.Program, parentNode); node.AccessModifier = accMod; node.InheritanceModifier = inhMod; node.TypeIdentifier = typeIdentifier; node.Identifier = identifier; node.IsAsync = isAsync; node.IsPartial = isPartial; node.LeftParenthesisToken = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); while (!base.TokenStream.Done && base.TokenStream.Peek().Type != TokenType.RightParenthesis) { base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit)); node.Parameters.Add(base.TokenStream.Peek()); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); } node.RightParenthesisToken = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.LeftCurlyBracket && base.TokenStream.Peek().Type != TokenType.Semicolon)) { throw new ParsingException("Expected \"{\" or \";\".", new List<TokenType> { TokenType.LeftCurlyBracket, TokenType.Semicolon }); } if (base.TokenStream.Peek().Type == TokenType.LeftCurlyBracket) { var blockNode = new BlockSyntax(base.TokenStream.Program, parentNode, null); new BlockSyntaxVisitor(base.TokenStream).Visit(blockNode); node.StatementBlock = blockNode; } else if (base.TokenStream.Peek().Type == TokenType.Semicolon) { node.SemicolonToken = base.TokenStream.Peek(); } parentNode.MethodDeclarations.Add(node); }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">MachineDeclarationNode</param> /// <param name="groupNode">StateGroupDeclaration</param> internal StateGroupDeclaration(IPSharpProgram program, MachineDeclaration machineNode, StateGroupDeclaration groupNode) : base(program) { this.Machine = machineNode; this.Group = groupNode; this.StateDeclarations = new List <StateDeclaration>(); this.StateGroupDeclarations = new List <StateGroupDeclaration>(); }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">PMachineDeclarationNode</param> /// <param name="isStart">Is start state</param> /// <param name="isModel">Is a model</param> internal StateDeclaration(IPSharpProgram program, MachineDeclaration machineNode, bool isStart, bool isModel) : base(program, isModel) { this.IsStart = isStart; this.Machine = machineNode; this.GotoStateTransitions = new Dictionary <Token, Token>(); this.PushStateTransitions = new Dictionary <Token, Token>(); this.ActionBindings = new Dictionary <Token, Token>(); this.TransitionsOnExitActions = new Dictionary <Token, BlockSyntax>(); this.ActionHandlers = new Dictionary <Token, BlockSyntax>(); this.DeferredEvents = new HashSet <Token>(); this.IgnoredEvents = new HashSet <Token>(); }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">MachineDeclarationNode</param> /// <param name="groupNode">StateGroupDeclaration</param> /// <param name="isStart">Is start state</param> /// <param name="isHot">Is hot state</param> /// <param name="isCold">Is cold state</param> internal StateDeclaration(IPSharpProgram program, MachineDeclaration machineNode, StateGroupDeclaration groupNode, bool isStart, bool isHot, bool isCold) : base(program) { this.Machine = machineNode; this.Group = groupNode; this.IsStart = isStart; this.IsHot = isHot; this.IsCold = isCold; this.GotoStateTransitions = new Dictionary <Token, List <Token> >(); this.PushStateTransitions = new Dictionary <Token, List <Token> >(); this.ActionBindings = new Dictionary <Token, Token>(); this.TransitionsOnExitActions = new Dictionary <Token, BlockSyntax>(); this.ActionHandlers = new Dictionary <Token, BlockSyntax>(); this.DeferredEvents = new HashSet <Token>(); this.IgnoredEvents = new HashSet <Token>(); this.ResolvedEventIdentifierTokens = new Dictionary <Token, Tuple <List <Token>, int> >(); this.RewrittenMethods = new HashSet <QualifiedMethod>(); }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">MachineDeclarationNode</param> /// <param name="groupNode">StateGroupDeclaration</param> /// <param name="modSet">Modifier set</param> internal StateDeclaration(IPSharpProgram program, MachineDeclaration machineNode, StateGroupDeclaration groupNode, ModifierSet modSet) : base(program) { this.Machine = machineNode; this.Group = groupNode; this.AccessModifier = modSet.AccessModifier; this.IsStart = modSet.IsStart; this.IsHot = modSet.IsHot; this.IsCold = modSet.IsCold; this.GotoStateTransitions = new Dictionary <Token, List <Token> >(); this.PushStateTransitions = new Dictionary <Token, List <Token> >(); this.ActionBindings = new Dictionary <Token, Token>(); this.TransitionsOnExitActions = new Dictionary <Token, AnonymousActionHandler>(); this.ActionHandlers = new Dictionary <Token, AnonymousActionHandler>(); this.DeferredEvents = new HashSet <Token>(); this.IgnoredEvents = new HashSet <Token>(); this.ResolvedEventIdentifierTokens = new Dictionary <Token, Tuple <List <Token>, int> >(); this.RewrittenMethods = new HashSet <QualifiedMethod>(); }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">MachineDeclarationNode</param> /// <param name="groupNode">StateGroupDeclaration</param> /// <param name="modSet">Modifier set</param> internal StateDeclaration(IPSharpProgram program, MachineDeclaration machineNode, StateGroupDeclaration groupNode, ModifierSet modSet) : base(program) { this.Machine = machineNode; this.Group = groupNode; this.AccessModifier = modSet.AccessModifier; this.IsStart = modSet.IsStart; this.IsHot = modSet.IsHot; this.IsCold = modSet.IsCold; this.IsAbstract = modSet.InheritanceModifier == InheritanceModifier.Abstract; this.GotoStateTransitions = new Dictionary <Token, List <Token> >(); this.PushStateTransitions = new Dictionary <Token, List <Token> >(); this.ActionBindings = new Dictionary <Token, Token>(); this.TransitionsOnExitActions = new Dictionary <Token, AnonymousActionHandler>(); this.ActionHandlers = new Dictionary <Token, AnonymousActionHandler>(); this.DeferredEvents = new HashSet <Token>(); this.IgnoredEvents = new HashSet <Token>(); this.ResolvedEventIdentifierTokens = new Dictionary <Token, Tuple <List <Token>, int> >(); this.RewrittenMethods = new HashSet <QualifiedMethod>(); this.isNameofSupported = base.Program.GetProject().CompilationContext.Configuration.IsRewriteCSharpVersion(6, 0); }
/// <summary> /// Visits the syntax node. /// </summary> /// <param name="parentNode">Node</param> /// <param name="isModel">Is model</param> internal void Visit(MachineDeclaration parentNode, bool isModel) { var node = new PFunctionDeclaration(base.TokenStream.Program, parentNode.IsModel || isModel); if (isModel) { base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.FunDecl) { throw new ParsingException("Expected function declaration.", new List<TokenType> { TokenType.FunDecl }); } } node.FunctionKeyword = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Identifier) { throw new ParsingException("Expected identifier.", new List<TokenType> { TokenType.Identifier }); } node.Identifier = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.LeftParenthesis) { throw new ParsingException("Expected \"(\".", new List<TokenType> { TokenType.LeftParenthesis }); } node.LeftParenthesisToken = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); bool expectsColon = false; bool expectsType = false; bool expectsComma = false; while (!base.TokenStream.Done && base.TokenStream.Peek().Type != TokenType.RightParenthesis) { if ((!expectsColon && !expectsComma && !expectsType && base.TokenStream.Peek().Type != TokenType.Identifier) || (!expectsColon && !expectsComma && expectsType && base.TokenStream.Peek().Type != TokenType.MachineDecl && base.TokenStream.Peek().Type != TokenType.Int && base.TokenStream.Peek().Type != TokenType.Bool && base.TokenStream.Peek().Type != TokenType.Seq && base.TokenStream.Peek().Type != TokenType.Map && base.TokenStream.Peek().Type != TokenType.LeftParenthesis) || (expectsColon && base.TokenStream.Peek().Type != TokenType.Colon) || (expectsComma && base.TokenStream.Peek().Type != TokenType.Comma)) { break; } if (!expectsType && base.TokenStream.Peek().Type == TokenType.Identifier) { node.Parameters.Add(base.TokenStream.Peek()); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); expectsColon = true; } else if (base.TokenStream.Peek().Type == TokenType.Colon) { base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); expectsColon = false; expectsType = true; } else if (expectsType && (base.TokenStream.Peek().Type == TokenType.MachineDecl || base.TokenStream.Peek().Type == TokenType.Int || base.TokenStream.Peek().Type == TokenType.Bool || base.TokenStream.Peek().Type == TokenType.Seq || base.TokenStream.Peek().Type == TokenType.Map || base.TokenStream.Peek().Type == TokenType.LeftParenthesis)) { PBaseType type = null; new TypeIdentifierVisitor(base.TokenStream).Visit(ref type); node.ParameterTypes.Add(type); expectsType = false; expectsComma = true; } else if (base.TokenStream.Peek().Type == TokenType.Comma) { base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); expectsComma = false; } } node.RightParenthesisToken = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.Colon && base.TokenStream.Peek().Type != TokenType.LeftSquareBracket && 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(); PBaseType type = null; new TypeIdentifierVisitor(base.TokenStream).Visit(ref type); node.ReturnType = type; } if (base.TokenStream.Peek().Type == TokenType.LeftSquareBracket) { while (!base.TokenStream.Done && base.TokenStream.Peek().Type != TokenType.LeftCurlyBracket) { 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 }); } var blockNode = new BlockSyntax(base.TokenStream.Program, parentNode, null, node.IsModel); new BlockSyntaxVisitor(base.TokenStream).Visit(blockNode); node.StatementBlock = blockNode; parentNode.FunctionDeclarations.Add(node); }
/// <summary> /// Constructor /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">MachineDeclarationNode</param> internal FieldDeclaration(IPSharpProgram program, MachineDeclaration machineNode) : base(program) { this.Machine = machineNode; }
/// <summary> /// Constructor /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">MachineDeclarationNode</param> /// <param name="isModel">Is a model</param> internal FieldDeclaration(IPSharpProgram program, MachineDeclaration machineNode, bool isModel) : base(program, isModel) { this.Machine = machineNode; }
/// <summary> /// Tries to return the parent machine identifier, if any. /// </summary> /// <param name="node">SyntaxNode</param> /// <param name="machine">MachineDeclaration</param> /// <returns>Boolean</returns> protected bool TryGetParentMachine(SyntaxNode node, out MachineDeclaration machine) { var result = false; machine = null; var ancestors = node.Ancestors().OfType<ClassDeclarationSyntax>().ToList(); foreach (var ancestor in ancestors) { machine = this.Project.PSharpPrograms. SelectMany(p => p.NamespaceDeclarations). SelectMany(n => n.MachineDeclarations). FirstOrDefault(s => s.Identifier.TextUnit.Text.Equals(ancestor.Identifier.ValueText)); if (machine != null) { result = true; break; } } return result; }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">MachineDeclarationNode</param> internal MethodDeclaration(IPSharpProgram program, MachineDeclaration machineNode) : base(program) { this.Parameters = new List <Token>(); this.Machine = machineNode; }
/// <summary> /// Visits the syntax node. /// </summary> /// <param name="parentNode">Node</param> /// <param name="accMod">Access modifier</param> /// <param name="inhMod">Inheritance modifier</param> /// <param name="isAsync">Is async</param> /// <param name="isPartial">Is partial</param> internal void Visit(MachineDeclaration parentNode, AccessModifier accMod, InheritanceModifier inhMod, bool isAsync, bool isPartial) { TextUnit textUnit = null; new TypeIdentifierVisitor(base.TokenStream).Visit(ref textUnit); var typeIdentifier = new Token(textUnit, TokenType.TypeIdentifier); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Identifier) { throw new ParsingException("Expected field or method identifier.", new List<TokenType> { TokenType.Identifier }); } var identifierToken = base.TokenStream.Peek(); 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) { new MethodDeclarationVisitor(base.TokenStream).Visit(parentNode, typeIdentifier, identifierToken, accMod, inhMod, isAsync, isPartial); } else if (base.TokenStream.Peek().Type == TokenType.Semicolon) { if (inhMod == InheritanceModifier.Abstract) { throw new ParsingException("A field cannot be abstract.", new List<TokenType>()); } else if (inhMod == InheritanceModifier.Virtual) { throw new ParsingException("A field cannot be virtual.", new List<TokenType>()); } else if (inhMod == InheritanceModifier.Override) { throw new ParsingException("A field cannot be overriden.", new List<TokenType>()); } if (isAsync) { throw new ParsingException("A field cannot be async.", new List<TokenType>()); } if (isPartial) { throw new ParsingException("A field cannot be partial.", new List<TokenType>()); } var node = new FieldDeclaration(base.TokenStream.Program, parentNode); node.AccessModifier = accMod; node.TypeIdentifier = typeIdentifier; node.Identifier = identifierToken; node.SemicolonToken = base.TokenStream.Peek(); parentNode.FieldDeclarations.Add(node); } }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">PMachineDeclarationNode</param> /// <param name="isStart">Is start state</param> /// <param name="isModel">Is a model</param> internal StateDeclaration(IPSharpProgram program, MachineDeclaration machineNode, bool isStart, bool isModel) : base(program, isModel) { this.IsStart = isStart; this.Machine = machineNode; this.GotoStateTransitions = new Dictionary<Token, Token>(); this.PushStateTransitions = new Dictionary<Token, Token>(); this.ActionBindings = new Dictionary<Token, Token>(); this.TransitionsOnExitActions = new Dictionary<Token, BlockSyntax>(); this.ActionHandlers = new Dictionary<Token, BlockSyntax>(); this.DeferredEvents = new HashSet<Token>(); this.IgnoredEvents = new HashSet<Token>(); }
/// <summary> /// Visits the next intra-machine declration. /// </summary> /// <param name="node">Node</param> private void VisitNextPSharpIntraMachineDeclaration(MachineDeclaration node) { bool fixpoint = false; while (!fixpoint) { 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.StartState: case TokenType.HotState: case TokenType.ColdState: case TokenType.StateDecl: case TokenType.StateGroupDecl: case TokenType.Void: case TokenType.MachineDecl: case TokenType.Object: case TokenType.String: case TokenType.Sbyte: case TokenType.Byte: case TokenType.Short: case TokenType.Ushort: case TokenType.Int: case TokenType.Uint: case TokenType.Long: case TokenType.Ulong: case TokenType.Char: case TokenType.Bool: case TokenType.Decimal: case TokenType.Float: case TokenType.Double: case TokenType.Identifier: case TokenType.Private: case TokenType.Protected: case TokenType.Internal: case TokenType.Public: case TokenType.Async: case TokenType.Partial: this.VisitMachineLevelDeclaration(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: base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit, TokenType.MachineRightCurlyBracket)); node.RightCurlyBracketToken = base.TokenStream.Peek(); fixpoint = true; break; default: throw new ParsingException("Unexpected token '" + base.TokenStream.Peek().TextUnit.Text + "'.", new List<TokenType>()); } if (base.TokenStream.Done) { throw new ParsingException("Expected \"}\".", new List<TokenType> { TokenType.Private, TokenType.Protected, TokenType.StartState, TokenType.HotState, TokenType.ColdState, TokenType.StateDecl, TokenType.StateGroupDecl, TokenType.LeftSquareBracket, TokenType.RightCurlyBracket }); } } }
/// <summary> /// Constructor /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">PMachineDeclarationNode</param> /// <param name="isModel">Is a model</param> internal PFieldDeclaration(IPSharpProgram program, MachineDeclaration machineNode, bool isModel) : base(program, machineNode, isModel) { }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">MachineDeclarationNode</param> /// <param name="groupNode">StateGroupDeclaration</param> /// <param name="isStart">Is start state</param> /// <param name="isHot">Is hot state</param> /// <param name="isCold">Is cold state</param> internal StateDeclaration(IPSharpProgram program, MachineDeclaration machineNode, StateGroupDeclaration groupNode, bool isStart, bool isHot, bool isCold) : base(program) { this.Machine = machineNode; this.Group = groupNode; this.IsStart = isStart; this.IsHot = isHot; this.IsCold = isCold; this.GotoStateTransitions = new Dictionary<Token, List<Token>>(); this.PushStateTransitions = new Dictionary<Token, List<Token>>(); this.ActionBindings = new Dictionary<Token, Token>(); this.TransitionsOnExitActions = new Dictionary<Token, BlockSyntax>(); this.ActionHandlers = new Dictionary<Token, BlockSyntax>(); this.DeferredEvents = new HashSet<Token>(); this.IgnoredEvents = new HashSet<Token>(); this.ResolvedEventIdentifierTokens = new Dictionary<Token, Tuple<List<Token>, int>>(); this.RewrittenMethods = new HashSet<QualifiedMethod>(); }
/// <summary> /// Visits the syntax node. /// </summary> /// <param name="parentNode">Containing machine</param> /// <param name="groupNode">Containing group</param> /// <param name="accMod">Access modifier</param> internal void Visit(MachineDeclaration parentNode, StateGroupDeclaration groupNode, AccessModifier accMod) { var node = new StateGroupDeclaration(base.TokenStream.Program, parentNode, groupNode); node.AccessModifier = accMod; node.StateGroupKeyword = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Identifier) { throw new ParsingException("Expected state group identifier.", new List<TokenType> { TokenType.Identifier }); } base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit, TokenType.StateGroupIdentifier)); node.Identifier = 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.StateGroupLeftCurlyBracket)); node.LeftCurlyBracketToken = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); this.VisitNextPSharpIntraGroupDeclaration(node); if (groupNode == null) { parentNode.StateGroupDeclarations.Add(node); } else { groupNode.StateGroupDeclarations.Add(node); } var stateDeclarations = node.GetAllStateDeclarations(); if (stateDeclarations.Count == 0) { throw new ParsingException("A state group must declare at least one state.", new List<TokenType>()); } }
/// <summary> /// Visits a machine level declaration. /// </summary> /// <param name="parentNode">Node</param> private void VisitMachineLevelDeclaration(MachineDeclaration parentNode) { AccessModifier am = AccessModifier.None; InheritanceModifier im = InheritanceModifier.None; bool isStart = false; bool isHot = false; bool isCold = false; bool isAsync = false; bool isPartial = false; while (!base.TokenStream.Done && base.TokenStream.Peek().Type != TokenType.StateDecl && base.TokenStream.Peek().Type != TokenType.StateGroupDecl && base.TokenStream.Peek().Type != TokenType.MachineDecl && base.TokenStream.Peek().Type != TokenType.Void && 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 && base.TokenStream.Peek().Type != TokenType.Identifier) { 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 (isStart && base.TokenStream.Peek().Type == TokenType.StartState) { throw new ParsingException("Duplicate start state modifier.", new List<TokenType>()); } else if (isHot && base.TokenStream.Peek().Type == TokenType.HotState) { throw new ParsingException("Duplicate hot state modifier.", new List<TokenType>()); } else if (isCold && base.TokenStream.Peek().Type == TokenType.ColdState) { throw new ParsingException("Duplicate cold state modifier.", new List<TokenType>()); } else if ((isCold && base.TokenStream.Peek().Type == TokenType.HotState) || (isHot && base.TokenStream.Peek().Type == TokenType.ColdState)) { throw new ParsingException("State cannot be both hot and cold.", new List<TokenType>()); } else if (isAsync && base.TokenStream.Peek().Type == TokenType.Async) { throw new ParsingException("Duplicate async method modifier.", new List<TokenType>()); } else if (isPartial && base.TokenStream.Peek().Type == TokenType.Partial) { throw new ParsingException("Duplicate partial method 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.Virtual) { im = InheritanceModifier.Virtual; } else if (base.TokenStream.Peek().Type == TokenType.Override) { im = InheritanceModifier.Override; } else if (base.TokenStream.Peek().Type == TokenType.StartState) { isStart = true; } else if (base.TokenStream.Peek().Type == TokenType.HotState) { isHot = true; } else if (base.TokenStream.Peek().Type == TokenType.ColdState) { isCold = true; } else if (base.TokenStream.Peek().Type == TokenType.Async) { isAsync = true; } 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.StateDecl && base.TokenStream.Peek().Type != TokenType.StateGroupDecl && base.TokenStream.Peek().Type != TokenType.MachineDecl && base.TokenStream.Peek().Type != TokenType.Void && 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 && base.TokenStream.Peek().Type != TokenType.Identifier)) { throw new ParsingException("Expected state, group or method declaration.", new List<TokenType> { TokenType.StateDecl, TokenType.StateGroupDecl, TokenType.MachineDecl, TokenType.Void, TokenType.Object, TokenType.String, TokenType.Sbyte, TokenType.Byte, TokenType.Short, TokenType.Ushort, TokenType.Int, TokenType.Uint, TokenType.Long, TokenType.Ulong, TokenType.Char, TokenType.Bool, TokenType.Decimal, TokenType.Float, TokenType.Double, TokenType.Identifier }); } if (base.TokenStream.Peek().Type == TokenType.StateDecl) { if (am == AccessModifier.Public) { throw new ParsingException("A state cannot be public.", new List<TokenType>()); } else if (am == AccessModifier.Internal) { throw new ParsingException("A state cannot be internal.", new List<TokenType>()); } if (im == InheritanceModifier.Abstract) { throw new ParsingException("A state cannot be abstract.", new List<TokenType>()); } else if (im == InheritanceModifier.Virtual) { throw new ParsingException("A state cannot be virtual.", new List<TokenType>()); } else if (im == InheritanceModifier.Override) { throw new ParsingException("A state cannot be overriden.", new List<TokenType>()); } if (isAsync) { throw new ParsingException("A state cannot be async.", new List<TokenType>()); } if (isPartial) { throw new ParsingException("A state cannot be partial.", new List<TokenType>()); } new StateDeclarationVisitor(base.TokenStream).Visit(parentNode, null, isStart, isHot, isCold, am); } else if (base.TokenStream.Peek().Type == TokenType.StateGroupDecl) { if (am == AccessModifier.Public) { throw new ParsingException("A state group cannot be public.", new List<TokenType>()); } else if (am == AccessModifier.Internal) { throw new ParsingException("A state group cannot be internal.", new List<TokenType>()); } if (im == InheritanceModifier.Abstract) { throw new ParsingException("A state group cannot be abstract.", new List<TokenType>()); } else if (im == InheritanceModifier.Virtual) { throw new ParsingException("A state group cannot be virtual.", new List<TokenType>()); } else if (im == InheritanceModifier.Override) { throw new ParsingException("A state group cannot be overriden.", new List<TokenType>()); } if (isAsync) { throw new ParsingException("A state group cannot be async.", new List<TokenType>()); } if (isPartial) { throw new ParsingException("A state group cannot be partial.", new List<TokenType>()); } if (isStart) { throw new ParsingException("A state group cannot be marked start.", new List<TokenType>()); } else if (isHot) { throw new ParsingException("A state group cannot be hot.", new List<TokenType>()); } else if (isCold) { throw new ParsingException("A state group cannot be cold.", new List<TokenType>()); } new StateGroupDeclarationVisitor(base.TokenStream).Visit(parentNode, null, am); } else { if (am == AccessModifier.Public) { throw new ParsingException("A field or method cannot be public.", new List<TokenType>()); } else if (am == AccessModifier.Internal) { throw new ParsingException("A field or method cannot be internal.", new List<TokenType>()); } new FieldOrMethodDeclarationVisitor(base.TokenStream).Visit(parentNode, am, im, isAsync, isPartial); } }
/// <summary> /// Constructor /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">MachineDeclarationNode</param> /// <param name="modSet">Modifier set</param> internal FieldDeclaration(IPSharpProgram program, MachineDeclaration machineNode, ModifierSet modSet) : base(program) { this.Machine = machineNode; this.AccessModifier = modSet.AccessModifier; }
/// <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 the next intra-machine declration. /// </summary> /// <param name="node">Node</param> private void VisitNextPIntraMachineDeclaration(MachineDeclaration node) { bool fixpoint = false; while (!fixpoint) { 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.StartState: this.VisitStartStateModifier(node); base.TokenStream.Index++; break; case TokenType.StateDecl: new StateDeclarationVisitor(base.TokenStream).Visit(node, false, AccessModifier.None); base.TokenStream.Index++; break; case TokenType.ModelDecl: new FunctionDeclarationVisitor(base.TokenStream).Visit(node, true); base.TokenStream.Index++; break; case TokenType.FunDecl: new FunctionDeclarationVisitor(base.TokenStream).Visit(node, false); base.TokenStream.Index++; break; case TokenType.Var: new FieldDeclarationVisitor(base.TokenStream).Visit(node); base.TokenStream.Index++; break; case TokenType.ColdState: case TokenType.HotState: base.TokenStream.Index++; break; case TokenType.RightCurlyBracket: base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit, TokenType.MachineRightCurlyBracket)); node.RightCurlyBracketToken = base.TokenStream.Peek(); base.TokenStream.CurrentMachine = ""; fixpoint = true; break; default: throw new ParsingException("Unexpected token.", new List<TokenType>()); } if (base.TokenStream.Done) { throw new ParsingException("Expected \"}\".", new List<TokenType> { TokenType.StartState, TokenType.StateDecl, TokenType.FunDecl, TokenType.Var }); } } }
/// <summary> /// Visits a start state modifier. /// </summary> /// <param name="parentNode">Node</param> private void VisitStartStateModifier(MachineDeclaration parentNode) { base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.StateDecl && base.TokenStream.Peek().Type != TokenType.ColdState && base.TokenStream.Peek().Type != TokenType.HotState)) { throw new ParsingException("Expected state declaration.", new List<TokenType> { TokenType.StateDecl }); } if (base.TokenStream.Peek().Type == TokenType.ColdState || base.TokenStream.Peek().Type == TokenType.HotState) { base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.StateDecl) { throw new ParsingException("Expected state declaration.", new List<TokenType> { TokenType.StateDecl }); } } new StateDeclarationVisitor(base.TokenStream).Visit(parentNode, true, AccessModifier.None); }
/// <summary> /// Visits the syntax node. /// </summary> /// <param name="parentNode">Node</param> internal void Visit(MachineDeclaration parentNode) { var nodes = new List<PFieldDeclaration>(); var fieldKeyword = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Identifier) { throw new ParsingException("Expected identifier.", new List<TokenType> { TokenType.Identifier }); } nodes.Add(new PFieldDeclaration(base.TokenStream.Program, parentNode, parentNode.IsModel)); nodes[nodes.Count - 1].FieldKeyword = fieldKeyword; nodes[nodes.Count - 1].Identifier = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); bool expectsComma = true; while (!base.TokenStream.Done && base.TokenStream.Peek().Type != TokenType.Colon) { if ((!expectsComma && base.TokenStream.Peek().Type != TokenType.Identifier) || (expectsComma && base.TokenStream.Peek().Type != TokenType.Comma)) { break; } if (base.TokenStream.Peek().Type == TokenType.Identifier) { nodes.Add(new PFieldDeclaration(base.TokenStream.Program, parentNode, parentNode.IsModel)); nodes[nodes.Count - 1].FieldKeyword = fieldKeyword; nodes[nodes.Count - 1].Identifier = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); expectsComma = true; } else if (base.TokenStream.Peek().Type == TokenType.Comma) { base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); expectsComma = false; } } if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Colon) { throw new ParsingException("Expected \":\".", new List<TokenType> { TokenType.Colon }); } foreach (var node in nodes) { node.ColonToken = base.TokenStream.Peek(); } base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); PBaseType type = null; new TypeIdentifierVisitor(base.TokenStream).Visit(ref type); foreach (var node in nodes) { node.Type = type; } if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Semicolon) { throw new ParsingException("Expected \";\".", new List<TokenType> { TokenType.Semicolon }); } foreach (var node in nodes) { node.SemicolonToken = base.TokenStream.Peek(); parentNode.FieldDeclarations.Add(node); } }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">MachineDeclarationNode</param> internal MethodDeclaration(IPSharpProgram program, MachineDeclaration machineNode) : base(program) { this.Parameters = new List<Token>(); this.Machine = machineNode; }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="machineNode">MachineDeclarationNode</param> /// <param name="groupNode">StateGroupDeclaration</param> internal StateGroupDeclaration(IPSharpProgram program, MachineDeclaration machineNode, StateGroupDeclaration groupNode) : base(program) { this.Machine = machineNode; this.Group = groupNode; this.StateDeclarations = new List<StateDeclaration>(); this.StateGroupDeclarations = new List<StateGroupDeclaration>(); }
/// <summary> /// Visits the syntax node. /// </summary> /// <param name="parentNode">Node</param> /// <param name="groupNode">Parent state group</param> /// <param name="isStart">Is start state</param> /// <param name="isHot">Is start state</param> /// <param name="isCold">Is start state</param> /// <param name="accMod">Access modifier</param> internal void Visit(MachineDeclaration parentNode, StateGroupDeclaration groupNode, bool isStart, bool isHot, bool isCold, AccessModifier accMod) { var node = new StateDeclaration(base.TokenStream.Program, parentNode, groupNode, isStart, isHot, isCold); node.AccessModifier = accMod; node.StateKeyword = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Identifier) { throw new ParsingException("Expected state identifier.", new List<TokenType> { TokenType.Identifier }); } base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit, TokenType.StateIdentifier)); node.Identifier = 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.StateLeftCurlyBracket)); node.LeftCurlyBracketToken = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Program is PSharpProgram) { this.VisitNextPSharpIntraStateDeclaration(node); } else { this.VisitNextPIntraStateDeclaration(node); } // Insert into (immediately) containing group or machine declaration. if (groupNode != null) { groupNode.StateDeclarations.Add(node); } else { parentNode.StateDeclarations.Add(node); } }