/// <summary>
        /// Visits a group level declaration.
        /// </summary>
        private void VisitGroupLevelDeclaration(StateGroupDeclaration parentNode, TokenRange tokenRange)
        {
            ModifierSet modSet = ModifierSet.CreateDefault();

            while (!this.TokenStream.Done &&
                   this.TokenStream.Peek().Type != TokenType.StateDecl &&
                   this.TokenStream.Peek().Type != TokenType.StateGroupDecl &&
                   this.TokenStream.Peek().Type != TokenType.MachineDecl)
            {
                new ModifierVisitor(this.TokenStream).Visit(modSet);

                this.TokenStream.Index++;
                this.TokenStream.SkipWhiteSpaceAndCommentTokens();
            }

            if (this.TokenStream.Done ||
                (this.TokenStream.Peek().Type != TokenType.StateDecl &&
                 this.TokenStream.Peek().Type != TokenType.StateGroupDecl))
            {
                throw new ParsingException("Expected state or group declaration.", this.TokenStream.Peek(), TokenType.StateDecl, TokenType.StateGroupDecl);
            }

            if (this.TokenStream.Peek().Type == TokenType.StateDecl)
            {
                new StateDeclarationVisitor(this.TokenStream).Visit(parentNode.Machine, parentNode, modSet, tokenRange.Start());
            }
            else if (this.TokenStream.Peek().Type == TokenType.StateGroupDecl)
            {
                new StateGroupDeclarationVisitor(this.TokenStream).Visit(parentNode.Machine, parentNode, modSet, tokenRange.Start());
            }
        }
        /// <summary>
        /// Visits the syntax node.
        /// </summary>
        internal void Visit(MachineDeclaration parentNode, StateGroupDeclaration groupNode, ModifierSet modSet, TokenRange tokenRange)
        {
            this.CheckStateGroupModifierSet(modSet);

            var node = new StateGroupDeclaration(this.TokenStream.Program, parentNode, groupNode);

            node.AccessModifier    = modSet.AccessModifier;
            node.StateGroupKeyword = this.TokenStream.Peek();

            this.TokenStream.Index++;
            this.TokenStream.SkipWhiteSpaceAndCommentTokens();

            if (this.TokenStream.Done ||
                this.TokenStream.Peek().Type != TokenType.Identifier)
            {
                throw new ParsingException("Expected state group identifier.", this.TokenStream.Peek(), TokenType.Identifier);
            }

            this.TokenStream.Swap(TokenType.StateGroupIdentifier);
            node.Identifier       = this.TokenStream.Peek();
            node.HeaderTokenRange = tokenRange.FinishAndClone();

            this.TokenStream.Index++;
            this.TokenStream.SkipWhiteSpaceAndCommentTokens();

            if (this.TokenStream.Done ||
                this.TokenStream.Peek().Type != TokenType.LeftCurlyBracket)
            {
                throw new ParsingException("Expected \"{\".", this.TokenStream.Peek(), TokenType.LeftCurlyBracket);
            }

            this.TokenStream.Swap(TokenType.StateGroupLeftCurlyBracket);

            node.LeftCurlyBracketToken = this.TokenStream.Peek();

            this.TokenStream.Index++;
            this.TokenStream.SkipWhiteSpaceAndCommentTokens();

            this.VisitNextPSharpIntraGroupDeclaration(node);

            if (groupNode is 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.", this.TokenStream.Peek());
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Visits a group level declaration.
        /// </summary>
        /// <param name="parentNode">Node</param>
        private void VisitGroupLevelDeclaration(StateGroupDeclaration parentNode)
        {
            ModifierSet modSet = ModifierSet.CreateDefault();

            while (!base.TokenStream.Done &&
                   base.TokenStream.Peek().Type != TokenType.StateDecl &&
                   base.TokenStream.Peek().Type != TokenType.StateGroupDecl &&
                   base.TokenStream.Peek().Type != TokenType.MachineDecl)
            {
                new ModifierVisitor(base.TokenStream).Visit(modSet);

                base.TokenStream.Index++;
                base.TokenStream.SkipWhiteSpaceAndCommentTokens();
            }

            if (base.TokenStream.Done ||
                (base.TokenStream.Peek().Type != TokenType.StateDecl &&
                 base.TokenStream.Peek().Type != TokenType.StateGroupDecl))
            {
                throw new ParsingException("Expected state or group declaration.",
                                           new List <TokenType>
                {
                    TokenType.StateDecl,
                    TokenType.StateGroupDecl
                });
            }

            if (base.TokenStream.Peek().Type == TokenType.StateDecl)
            {
                new StateDeclarationVisitor(base.TokenStream).Visit(parentNode.Machine, parentNode, modSet);
            }
            else if (base.TokenStream.Peek().Type == TokenType.StateGroupDecl)
            {
                new StateGroupDeclarationVisitor(base.TokenStream).Visit(parentNode.Machine, parentNode, modSet);
            }
        }
        /// <summary>
        /// Visits the next intra-group declaration.
        /// </summary>
        private void VisitNextPSharpIntraGroupDeclaration(StateGroupDeclaration node)
        {
            bool fixpoint   = false;
            var  tokenRange = new TokenRange(this.TokenStream);

            while (!fixpoint)
            {
                if (!this.TokenStream.Done)
                {
                    var token = this.TokenStream.Peek();
                    switch (token.Type)
                    {
                    case TokenType.WhiteSpace:
                    case TokenType.QuotedString:
                    case TokenType.Comment:
                    case TokenType.NewLine:
                        this.TokenStream.Index++;
                        break;

                    case TokenType.CommentLine:
                    case TokenType.Region:
                        this.TokenStream.SkipWhiteSpaceAndCommentTokens();
                        break;

                    case TokenType.CommentStart:
                        this.TokenStream.SkipWhiteSpaceAndCommentTokens();
                        break;

                    case TokenType.StartState:
                    case TokenType.HotState:
                    case TokenType.ColdState:
                    case TokenType.StateDecl:
                    case TokenType.StateGroupDecl:
                    case TokenType.Private:
                    case TokenType.Protected:
                    case TokenType.Internal:
                    case TokenType.Public:
                        this.VisitGroupLevelDeclaration(node, tokenRange.Start());
                        this.TokenStream.Index++;
                        break;

                    case TokenType.LeftSquareBracket:
                        this.TokenStream.Index++;
                        this.TokenStream.SkipWhiteSpaceAndCommentTokens();
                        new AttributeListVisitor(this.TokenStream).Visit();
                        this.TokenStream.Index++;
                        break;

                    case TokenType.RightCurlyBracket:
                        this.TokenStream.Swap(TokenType.MachineRightCurlyBracket);
                        node.RightCurlyBracketToken = this.TokenStream.Peek();
                        fixpoint = true;
                        break;

                    default:
                        throw new ParsingException("Unexpected token '" + this.TokenStream.Peek().TextUnit.Text + "'.", this.TokenStream.Peek());
                    }
                }

                if (this.TokenStream.Done)
                {
                    throw new ParsingException("Expected \"}\".", this.TokenStream.Peek(),
                                               TokenType.Private,
                                               TokenType.Protected,
                                               TokenType.StartState,
                                               TokenType.HotState,
                                               TokenType.ColdState,
                                               TokenType.StateDecl,
                                               TokenType.StateGroupDecl,
                                               TokenType.LeftSquareBracket,
                                               TokenType.RightCurlyBracket);
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Visits the syntax node.
        /// </summary>
        /// <param name="parentNode">Containing machine</param>
        /// <param name="groupNode">Containing group</param>
        /// <param name="modSet">Modifier set</param>
        internal void Visit(MachineDeclaration parentNode, StateGroupDeclaration groupNode, ModifierSet modSet)
        {
            this.CheckMachineStateModifierSet(modSet);

            var node = new StateDeclaration(base.TokenStream.Program, parentNode, groupNode, modSet);

            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);
            }
        }
        /// <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 group level declaration.
        /// </summary>
        /// <param name="parentNode">Node</param>
        private void VisitGroupLevelDeclaration(StateGroupDeclaration 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)
            {
                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))
            {
                throw new ParsingException("Expected state or group declaration.",
                                           new List <TokenType>
                {
                    TokenType.StateDecl,
                    TokenType.StateGroupDecl
                });
            }

            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.Machine,
                                                                    parentNode, 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.Machine, parentNode, am);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Visits the syntax node.
        /// </summary>
        internal void Visit(MachineDeclaration parentNode, StateGroupDeclaration groupNode, ModifierSet modSet, TokenRange tokenRange)
        {
            this.CheckMachineStateModifierSet(modSet);

            var node = new StateDeclaration(this.TokenStream.Program, parentNode, groupNode, modSet);

            node.StateKeyword = this.TokenStream.Peek();

            this.TokenStream.Index++;
            this.TokenStream.SkipWhiteSpaceAndCommentTokens();

            if (this.TokenStream.Done ||
                this.TokenStream.Peek().Type != TokenType.Identifier)
            {
                throw new ParsingException("Expected state identifier.", this.TokenStream.Peek(), TokenType.Identifier);
            }

            this.TokenStream.Swap(TokenType.StateIdentifier);
            node.Identifier       = this.TokenStream.Peek();
            node.HeaderTokenRange = tokenRange.FinishAndClone();

            this.TokenStream.Index++;
            this.TokenStream.SkipWhiteSpaceAndCommentTokens();

            // Check for inherited state.
            if (!this.TokenStream.Done && this.TokenStream.Peek().Type == TokenType.Colon)
            {
                this.TokenStream.Index++;
                this.TokenStream.SkipWhiteSpaceAndCommentTokens();
                if (this.TokenStream.Done || this.TokenStream.Peek().Type != TokenType.Identifier)
                {
                    throw new ParsingException("Expected state identifier.", this.TokenStream.Peek(), TokenType.Identifier);
                }

                this.TokenStream.Swap(TokenType.StateIdentifier);
                node.BaseStateToken = this.TokenStream.Peek();
                this.TokenStream.Index++;
                this.TokenStream.SkipWhiteSpaceAndCommentTokens();
            }

            if (this.TokenStream.Done ||
                this.TokenStream.Peek().Type != TokenType.LeftCurlyBracket)
            {
                throw new ParsingException("Expected \"{\".", this.TokenStream.Peek(), TokenType.LeftCurlyBracket);
            }

            this.TokenStream.Swap(TokenType.StateLeftCurlyBracket);

            node.LeftCurlyBracketToken = this.TokenStream.Peek();

            this.TokenStream.Index++;
            this.TokenStream.SkipWhiteSpaceAndCommentTokens();

            if (this.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);
            }
        }