/// <summary> /// Visits the syntax node. /// </summary> /// <param name="parentNode">Node</param> internal void Visit(StateDeclaration parentNode) { if (parentNode.ExitDeclaration != null) { throw new ParsingException("Duplicate exit declaration.", new List<TokenType>()); } var node = new ExitDeclaration(base.TokenStream.Program, parentNode.IsModel); node.ExitKeyword = 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 }); } var blockNode = new BlockSyntax(base.TokenStream.Program, parentNode.Machine, parentNode, node.IsModel); new BlockSyntaxVisitor(base.TokenStream).Visit(blockNode); node.StatementBlock = blockNode; parentNode.ExitDeclaration = node; }
/// <summary> /// Visits the syntax node. /// </summary> /// <param name="parentNode">Node</param> internal void Visit(BlockSyntax node) { node.OpenBraceToken = base.TokenStream.Peek(); var text = ""; int counter = 0; while (!base.TokenStream.Done) { text += base.TokenStream.Peek().TextUnit.Text; if (base.TokenStream.Peek().Type == TokenType.LeftCurlyBracket) { counter++; } else if (base.TokenStream.Peek().Type == TokenType.RightCurlyBracket) { counter--; } if (counter == 0) { break; } base.TokenStream.Index++; } node.Block = CSharpSyntaxTree.ParseText(text); }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="node">Node</param> internal ExpressionNode(IPSharpProgram program, BlockSyntax node) : base(program, node.IsModel) { this.Parent = node; this.StmtTokens = new List<Token>(); this.RewrittenStmtTokens = new List<Token>(); }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="node">Node</param> internal PExpressionNode(IPSharpProgram program, BlockSyntax node) : base(program, node) { this.Payloads = new List<PPayloadReceiveNode>(); this.PendingPayloads = new List<PPayloadReceiveNode>(); }
/// <summary> /// Adds a goto state transition. /// </summary> /// <param name="eventIdentifier">Token</param> /// <param name="eventIdentifierTokens">Tokens</param> /// <param name="stateIdentifiers">Token list</param> /// <param name="stmtBlock">Statement block</param> /// <returns>Boolean</returns> internal bool AddGotoStateTransition(Token eventIdentifier, List<Token> eventIdentifierTokens, List<Token> stateIdentifiers, BlockSyntax stmtBlock = null) { if (this.GotoStateTransitions.ContainsKey(eventIdentifier) || this.PushStateTransitions.ContainsKey(eventIdentifier) || this.ActionBindings.ContainsKey(eventIdentifier)) { return false; } this.GotoStateTransitions.Add(eventIdentifier, stateIdentifiers); if (stmtBlock != null) { this.TransitionsOnExitActions.Add(eventIdentifier, stmtBlock); } this.ResolvedEventIdentifierTokens[eventIdentifier] = Tuple.Create( eventIdentifierTokens, this.ResolvedEventIdentifierTokens.Count); return true; }
/// <summary> /// Adds an action binding. /// </summary> /// <param name="eventIdentifier">Token</param> /// <param name="eventIdentifierTokens">Tokens</param> /// <param name="stmtBlock">BlockSyntax</param> /// <returns>Boolean</returns> internal bool AddActionBinding(Token eventIdentifier, List<Token> eventIdentifierTokens, BlockSyntax stmtBlock) { if (this.GotoStateTransitions.ContainsKey(eventIdentifier) || this.PushStateTransitions.ContainsKey(eventIdentifier) || this.ActionBindings.ContainsKey(eventIdentifier)) { return false; } this.ActionBindings.Add(eventIdentifier, null); this.ActionHandlers.Add(eventIdentifier, stmtBlock); this.ResolvedEventIdentifierTokens[eventIdentifier] = Tuple.Create( eventIdentifierTokens, this.ResolvedEventIdentifierTokens.Count); return true; }
/// <summary> /// Adds a goto state transition. /// </summary> /// <param name="eventIdentifier">Token</param> /// <param name="stateIdentifier">Token</param> /// <param name="stmtBlock">Statement block</param> /// <returns>Boolean value</returns> internal bool AddGotoStateTransition(Token eventIdentifier, Token stateIdentifier, BlockSyntax stmtBlock = null) { if (this.GotoStateTransitions.ContainsKey(eventIdentifier) || this.PushStateTransitions.ContainsKey(eventIdentifier) || this.ActionBindings.ContainsKey(eventIdentifier)) { return false; } this.GotoStateTransitions.Add(eventIdentifier, stateIdentifier); if (stmtBlock != null) { this.TransitionsOnExitActions.Add(eventIdentifier, stmtBlock); } return true; }
/// <summary> /// Adds an action binding. /// </summary> /// <param name="eventIdentifier">Token</param> /// <param name="stateIdentifier">Token</param> /// <returns>Boolean value</returns> internal bool AddActionBinding(Token eventIdentifier, BlockSyntax stmtBlock) { if (this.GotoStateTransitions.ContainsKey(eventIdentifier) || this.PushStateTransitions.ContainsKey(eventIdentifier) || this.ActionBindings.ContainsKey(eventIdentifier)) { return false; } this.ActionBindings.Add(eventIdentifier, null); this.ActionHandlers.Add(eventIdentifier, stmtBlock); return true; }
/// <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> /// Visits the syntax node. /// </summary> /// <param name="parentNode">Node</param> /// <param name="typeIdentifier">Type identifier</param> /// <param name="identifier">Identifier</param> /// <param name="isModel">Is model</param> /// <param name="accMod">Access modifier</param> /// <param name="inhMod">Inheritance modifier</param> /// <param name="isAsync">Is async</param> internal void Visit(MachineDeclaration parentNode, Token typeIdentifier, Token identifier, bool isModel, AccessModifier accMod, InheritanceModifier inhMod, bool isAsync) { if (parentNode.IsModel) { isModel = true; } var node = new MethodDeclaration(base.TokenStream.Program, isModel); node.AccessModifier = accMod; node.InheritanceModifier = inhMod; node.TypeIdentifier = typeIdentifier; node.Identifier = identifier; node.IsAsync = isAsync; 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, parentNode.IsModel); 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="node">Node</param> internal PPayloadSendExpressionNode(IPSharpProgram program, BlockSyntax node) : base(program, node) { }
/// <summary> /// Visits the syntax node. /// </summary> /// <param name="parentNode">Node</param> internal void Visit(StateDeclaration parentNode) { 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 }); } var eventIdentifiers = new List<Token>(); bool expectsComma = false; while (!base.TokenStream.Done && base.TokenStream.Peek().Type != TokenType.DoAction && base.TokenStream.Peek().Type != TokenType.GotoState && base.TokenStream.Peek().Type != TokenType.PushState) { if ((!expectsComma && base.TokenStream.Peek().Type != TokenType.Identifier && base.TokenStream.Peek().Type != TokenType.HaltEvent && base.TokenStream.Peek().Type != TokenType.DefaultEvent) || (expectsComma && base.TokenStream.Peek().Type != TokenType.Comma)) { break; } if (base.TokenStream.Peek().Type == TokenType.Identifier || base.TokenStream.Peek().Type == TokenType.HaltEvent || base.TokenStream.Peek().Type == TokenType.DefaultEvent) { if (base.TokenStream.Peek().Type == TokenType.Identifier) { base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit, TokenType.EventIdentifier)); } eventIdentifiers.Add(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.DoAction && base.TokenStream.Peek().Type != TokenType.GotoState && base.TokenStream.Peek().Type != TokenType.PushState)) { throw new ParsingException("Expected \"do\", \"goto\" or \"push\".", new List<TokenType> { TokenType.DoAction, TokenType.GotoState, TokenType.PushState }); } if (base.TokenStream.Peek().Type == TokenType.DoAction) { base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.Identifier && base.TokenStream.Peek().Type != TokenType.LeftCurlyBracket)) { throw new ParsingException("Expected action identifier.", new List<TokenType> { TokenType.Identifier }); } if (base.TokenStream.Peek().Type == TokenType.LeftCurlyBracket) { var blockNode = new BlockSyntax(base.TokenStream.Program, parentNode.Machine, null, parentNode.IsModel); new BlockSyntaxVisitor(base.TokenStream).Visit(blockNode); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); foreach (var eventIdentifier in eventIdentifiers) { if (!parentNode.AddActionBinding(eventIdentifier, blockNode)) { throw new ParsingException("Unexpected action handler.", new List<TokenType>()); } } } else { base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit, TokenType.ActionIdentifier)); var actionIdentifier = base.TokenStream.Peek(); foreach (var eventIdentifier in eventIdentifiers) { if (!parentNode.AddActionBinding(eventIdentifier, actionIdentifier)) { throw new ParsingException("Unexpected action handler.", new List<TokenType>()); } } 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 }); } } else if (base.TokenStream.Peek().Type == TokenType.GotoState) { 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)); var stateIdentifier = base.TokenStream.Peek(); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.WithExit && base.TokenStream.Peek().Type != TokenType.Semicolon)) { throw new ParsingException("Expected \";\".", new List<TokenType> { TokenType.Semicolon }); } if (base.TokenStream.Peek().Type == TokenType.WithExit) { 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.Machine, null, parentNode.IsModel); new BlockSyntaxVisitor(base.TokenStream).Visit(blockNode); base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); foreach (var eventIdentifier in eventIdentifiers) { if (!parentNode.AddGotoStateTransition(eventIdentifier, stateIdentifier, blockNode)) { throw new ParsingException("Unexpected goto state transition.", new List<TokenType>()); } } if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Semicolon) { throw new ParsingException("Expected \";\".", new List<TokenType> { TokenType.Semicolon }); } } else { foreach (var eventIdentifier in eventIdentifiers) { if (!parentNode.AddGotoStateTransition(eventIdentifier, stateIdentifier)) { throw new ParsingException("Unexpected goto state transition.", new List<TokenType>()); } } } } else if (base.TokenStream.Peek().Type == TokenType.PushState) { if (parentNode.Machine.IsMonitor) { throw new ParsingException("Monitors cannot \"push\".", new List<TokenType>()); } 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)); var stateIdentifier = 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 }); } foreach (var eventIdentifier in eventIdentifiers) { if (!parentNode.AddPushStateTransition(eventIdentifier, stateIdentifier)) { throw new ParsingException("Unexpected push state transition.", new List<TokenType>()); } } } }
/// <summary> /// Visits the syntax node. /// </summary> /// <param name="parentNode">Node</param> internal void Visit(StateDeclaration parentNode) { 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 }); } var nameVisitor = new NameVisitor(base.TokenStream); // Consumes multiple generic event names. var eventIdentifiers = nameVisitor.ConsumeMultipleNames(TokenType.EventIdentifier, tt => nameVisitor.ConsumeGenericEventName(tt)); if (!base.TokenStream.Done && base.TokenStream.Peek().Type == TokenType.Identifier) { throw new ParsingException("Expected \",\".", new List<TokenType> { TokenType.Comma }); } if (!base.TokenStream.Done && (base.TokenStream.Peek().Type == TokenType.LeftAngleBracket || base.TokenStream.Peek().Type == TokenType.RightAngleBracket)) { throw new ParsingException("Invalid generic expression.", new List<TokenType> { }); } if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.DoAction && base.TokenStream.Peek().Type != TokenType.GotoState && base.TokenStream.Peek().Type != TokenType.PushState)) { throw new ParsingException("Expected \"do\", \"goto\" or \"push\".", new List<TokenType> { TokenType.DoAction, TokenType.GotoState, TokenType.PushState }); } var resolvedEventIdentifiers = new Dictionary<Token, List<Token>>(); foreach (var eventIdentifier in eventIdentifiers) { if (eventIdentifier.Count == 1) { // We don't want to collapse halt and default // events to event identifiers. resolvedEventIdentifiers.Add(eventIdentifier[0], eventIdentifier); } else { var identifierBuilder = new StringBuilder(); foreach (var token in eventIdentifier) { identifierBuilder.Append(token.TextUnit.Text); } TextUnit textUnit = new TextUnit(identifierBuilder.ToString(), eventIdentifier[0].TextUnit.Line); resolvedEventIdentifiers.Add(new Token(textUnit, TokenType.EventIdentifier), eventIdentifier); } } if (base.TokenStream.Peek().Type == TokenType.DoAction) { base.TokenStream.Index++; base.TokenStream.SkipWhiteSpaceAndCommentTokens(); if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.Identifier && base.TokenStream.Peek().Type != TokenType.LeftCurlyBracket)) { throw new ParsingException("Expected action identifier.", new List<TokenType> { TokenType.Identifier }); } if (base.TokenStream.Peek().Type == TokenType.LeftCurlyBracket) { var blockNode = new BlockSyntax(base.TokenStream.Program, parentNode.Machine, null); new BlockSyntaxVisitor(base.TokenStream).Visit(blockNode); foreach (var kvp in resolvedEventIdentifiers) { if (!parentNode.AddActionBinding(kvp.Key, kvp.Value, blockNode)) { throw new ParsingException("Unexpected action handler.", new List<TokenType>()); } } } else { base.TokenStream.Swap(new Token(base.TokenStream.Peek().TextUnit, TokenType.ActionIdentifier)); var actionIdentifier = base.TokenStream.Peek(); foreach (var kvp in resolvedEventIdentifiers) { if (!parentNode.AddActionBinding(kvp.Key, kvp.Value, actionIdentifier)) { throw new ParsingException("Unexpected action handler.", new List<TokenType>()); } } 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 }); } } } else if (base.TokenStream.Peek().Type == TokenType.GotoState) { var stateIdentifiers = this.ConsumeState(); if (base.TokenStream.Done || (base.TokenStream.Peek().Type != TokenType.WithExit && base.TokenStream.Peek().Type != TokenType.Semicolon)) { throw new ParsingException("Expected \";\".", new List<TokenType> { TokenType.Semicolon }); } if (base.TokenStream.Peek().Type == TokenType.WithExit) { 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.Machine, null); new BlockSyntaxVisitor(base.TokenStream).Visit(blockNode); foreach (var kvp in resolvedEventIdentifiers) { if (!parentNode.AddGotoStateTransition(kvp.Key, kvp.Value, stateIdentifiers, blockNode)) { throw new ParsingException("Unexpected goto state transition.", new List<TokenType>()); } } } else { foreach (var kvp in resolvedEventIdentifiers) { if (!parentNode.AddGotoStateTransition(kvp.Key, kvp.Value, stateIdentifiers)) { throw new ParsingException("Unexpected goto state transition.", new List<TokenType>()); } } } } else if (base.TokenStream.Peek().Type == TokenType.PushState) { if (parentNode.Machine.IsMonitor) { throw new ParsingException("Monitors cannot \"push\".", new List<TokenType>()); } var stateIdentifiers = this.ConsumeState(); if (base.TokenStream.Done || base.TokenStream.Peek().Type != TokenType.Semicolon) { throw new ParsingException("Expected \";\".", new List<TokenType> { TokenType.Semicolon }); } foreach (var kvp in resolvedEventIdentifiers) { if (!parentNode.AddPushStateTransition(kvp.Key, kvp.Value, stateIdentifiers)) { throw new ParsingException("Unexpected push state transition.", new List<TokenType>()); } } } }
/// <summary> /// Constructor. /// </summary> /// <param name="program">Program</param> /// <param name="node">Node</param> internal PExpressionNode(IPSharpProgram program, BlockSyntax node) : base(program, node) { this.Payloads = new List <PPayloadReceiveNode>(); this.PendingPayloads = new List <PPayloadReceiveNode>(); }