/// <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);
                }
            }
        }
        /// <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 a machine level declaration.
        /// </summary>
        private void VisitMachineLevelDeclaration(MachineDeclaration parentNode, TokenRange tokenRange)
        {
            var modSet = ModifierSet.CreateDefault();

            while (!this.TokenStream.Done &&
                   this.TokenStream.Peek().Type != TokenType.EventDecl &&
                   this.TokenStream.Peek().Type != TokenType.StateDecl &&
                   this.TokenStream.Peek().Type != TokenType.StateGroupDecl &&
                   this.TokenStream.Peek().Type != TokenType.MachineDecl &&
                   this.TokenStream.Peek().Type != TokenType.Void &&
                   this.TokenStream.Peek().Type != TokenType.Object &&
                   this.TokenStream.Peek().Type != TokenType.String &&
                   this.TokenStream.Peek().Type != TokenType.Sbyte &&
                   this.TokenStream.Peek().Type != TokenType.Byte &&
                   this.TokenStream.Peek().Type != TokenType.Short &&
                   this.TokenStream.Peek().Type != TokenType.Ushort &&
                   this.TokenStream.Peek().Type != TokenType.Int &&
                   this.TokenStream.Peek().Type != TokenType.Uint &&
                   this.TokenStream.Peek().Type != TokenType.Long &&
                   this.TokenStream.Peek().Type != TokenType.Ulong &&
                   this.TokenStream.Peek().Type != TokenType.Char &&
                   this.TokenStream.Peek().Type != TokenType.Bool &&
                   this.TokenStream.Peek().Type != TokenType.Decimal &&
                   this.TokenStream.Peek().Type != TokenType.Float &&
                   this.TokenStream.Peek().Type != TokenType.Double &&
                   this.TokenStream.Peek().Type != TokenType.Identifier)
            {
                new ModifierVisitor(this.TokenStream).Visit(modSet);

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

            if (this.TokenStream.Done ||
                (this.TokenStream.Peek().Type != TokenType.EventDecl &&
                 this.TokenStream.Peek().Type != TokenType.StateDecl &&
                 this.TokenStream.Peek().Type != TokenType.StateGroupDecl &&
                 this.TokenStream.Peek().Type != TokenType.MachineDecl &&
                 this.TokenStream.Peek().Type != TokenType.Void &&
                 this.TokenStream.Peek().Type != TokenType.Object &&
                 this.TokenStream.Peek().Type != TokenType.String &&
                 this.TokenStream.Peek().Type != TokenType.Sbyte &&
                 this.TokenStream.Peek().Type != TokenType.Byte &&
                 this.TokenStream.Peek().Type != TokenType.Short &&
                 this.TokenStream.Peek().Type != TokenType.Ushort &&
                 this.TokenStream.Peek().Type != TokenType.Int &&
                 this.TokenStream.Peek().Type != TokenType.Uint &&
                 this.TokenStream.Peek().Type != TokenType.Long &&
                 this.TokenStream.Peek().Type != TokenType.Ulong &&
                 this.TokenStream.Peek().Type != TokenType.Char &&
                 this.TokenStream.Peek().Type != TokenType.Bool &&
                 this.TokenStream.Peek().Type != TokenType.Decimal &&
                 this.TokenStream.Peek().Type != TokenType.Float &&
                 this.TokenStream.Peek().Type != TokenType.Double &&
                 this.TokenStream.Peek().Type != TokenType.Identifier))
            {
                throw new ParsingException("Expected event, state, group or method declaration.", this.TokenStream.Peek(),
                                           TokenType.EventDecl,
                                           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 (this.TokenStream.Peek().Type == TokenType.EventDecl)
            {
                new EventDeclarationVisitor(this.TokenStream).Visit(parentNode.Namespace, parentNode, modSet);
            }
            else if (this.TokenStream.Peek().Type == TokenType.StateDecl)
            {
                new StateDeclarationVisitor(this.TokenStream).Visit(parentNode, null, modSet, tokenRange.Start());
            }
            else if (this.TokenStream.Peek().Type == TokenType.StateGroupDecl)
            {
                new StateGroupDeclarationVisitor(this.TokenStream).Visit(parentNode, null, modSet, tokenRange.Start());
            }
            else
            {
                new MachineMemberDeclarationVisitor(this.TokenStream).Visit(parentNode, modSet);
            }
        }
        /// <summary>
        /// Visits the next intra-machine declaration.
        /// </summary>
        private void VisitNextPSharpIntraMachineDeclaration(MachineDeclaration 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.ExternDecl:
                        new EventDeclarationVisitor(this.TokenStream).VisitExternDeclaration(node.Namespace, node);
                        this.TokenStream.Index++;
                        break;

                    case TokenType.Abstract:
                    case TokenType.StartState:
                    case TokenType.HotState:
                    case TokenType.ColdState:
                    case TokenType.EventDecl:
                    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, 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);
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Visits the next intra-state declration.
        /// </summary>
        private void VisitNextPIntraStateDeclaration(StateDeclaration 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.Entry:
                        new StateEntryDeclarationVisitor(this.TokenStream).Visit(node, tokenRange.Start());
                        this.TokenStream.Index++;
                        break;

                    case TokenType.Exit:
                        new StateExitDeclarationVisitor(this.TokenStream).Visit(node, tokenRange.Start());
                        this.TokenStream.Index++;
                        break;

                    case TokenType.OnAction:
                        new StateActionDeclarationVisitor(this.TokenStream).Visit(node);
                        this.TokenStream.Index++;
                        break;

                    case TokenType.DeferEvent:
                        new DeferEventsDeclarationVisitor(this.TokenStream).Visit(node);
                        this.TokenStream.Index++;
                        break;

                    case TokenType.IgnoreEvent:
                        new IgnoreEventsDeclarationVisitor(this.TokenStream).Visit(node);
                        this.TokenStream.Index++;
                        break;

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

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

                if (this.TokenStream.Done)
                {
                    throw new ParsingException("Expected \"}\".", this.TokenStream.Peek(),
                                               TokenType.Entry,
                                               TokenType.Exit,
                                               TokenType.OnAction,
                                               TokenType.DeferEvent,
                                               TokenType.IgnoreEvent);
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// Visits the next intra-state declration.
        /// </summary>
        private void VisitNextPSharpIntraStateDeclaration(StateDeclaration node)
        {
            bool fixpoint   = false;
            var  tokenRange = new TokenRange(this.TokenStream);

            while (!fixpoint)
            {
                Token badToken = null;
                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.Async:
                        tokenRange.Start();
                        this.TokenStream.Index++;
                        this.TokenStream.SkipWhiteSpaceAndCommentTokens();
                        token = this.TokenStream.Peek();
                        switch (token.Type)
                        {
                        case TokenType.Entry:
                            new StateEntryDeclarationVisitor(this.TokenStream).Visit(node, tokenRange, isAsync: true);
                            this.TokenStream.Index++;
                            break;

                        case TokenType.Exit:
                            new StateExitDeclarationVisitor(this.TokenStream).Visit(node, tokenRange, isAsync: true);
                            this.TokenStream.Index++;
                            break;

                        default:
                            throw new ParsingException("'async' was used in an incorrect context.", this.TokenStream.Peek());
                        }

                        break;

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

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

                    case TokenType.Entry:
                        new StateEntryDeclarationVisitor(this.TokenStream).Visit(node, tokenRange.Start());
                        this.TokenStream.Index++;
                        break;

                    case TokenType.Exit:
                        new StateExitDeclarationVisitor(this.TokenStream).Visit(node, tokenRange.Start());
                        this.TokenStream.Index++;
                        break;

                    case TokenType.OnAction:
                        new StateActionDeclarationVisitor(this.TokenStream).Visit(node);
                        this.TokenStream.Index++;
                        break;

                    case TokenType.DeferEvent:
                        new DeferEventsDeclarationVisitor(this.TokenStream).Visit(node);
                        this.TokenStream.Index++;
                        break;

                    case TokenType.IgnoreEvent:
                        new IgnoreEventsDeclarationVisitor(this.TokenStream).Visit(node);
                        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.StateRightCurlyBracket);
                        node.RightCurlyBracketToken = this.TokenStream.Peek();
                        fixpoint = true;
                        break;

                    case TokenType.Private:
                    case TokenType.Protected:
                    case TokenType.Internal:
                    case TokenType.Public:
                        throw new ParsingException("State actions cannot have modifiers.", this.TokenStream.Peek());

                    case TokenType.Abstract:
                    case TokenType.Virtual:
                        throw new ParsingException("State actions cannot be abstract or virtual.", this.TokenStream.Peek());

                    default:
                        badToken = token;
                        break;
                    }
                }

                if (this.TokenStream.Done || badToken != null)
                {
                    throw new ParsingException($"Unexpected {(this.TokenStream.Done ? "end of file" : $"token: {badToken.Text}")}.", this.TokenStream.Peek(),
                                               TokenType.Entry,
                                               TokenType.Exit,
                                               TokenType.OnAction,
                                               TokenType.DeferEvent,
                                               TokenType.IgnoreEvent,
                                               TokenType.LeftSquareBracket,
                                               TokenType.RightCurlyBracket);
                }
            }
        }