Пример #1
0
        /// <summary>
        /// Visits the syntax node.
        /// </summary>
        internal void Visit(StateDeclaration parentNode, TokenRange tokenRange, bool isAsync = false)
        {
            if (parentNode.EntryDeclaration != null)
            {
                throw new ParsingException("Duplicate entry declaration.", this.TokenStream.Peek());
            }

            var node = new EntryDeclaration(this.TokenStream.Program, parentNode, isAsync);

            node.EntryKeyword     = 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);
            }

            var blockNode = new BlockSyntax(this.TokenStream.Program, parentNode.Machine, parentNode);

            new BlockSyntaxVisitor(this.TokenStream).Visit(blockNode);
            node.StatementBlock = blockNode;

            parentNode.EntryDeclaration = node;
        }
        /// <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());
            }
        }
Пример #3
0
        /// <summary>
        /// Visits the syntax node.
        /// </summary>
        internal void Visit(NamespaceDeclaration parentNode, bool isMonitor, ModifierSet modSet, TokenRange tokenRange)
        {
            if (isMonitor)
            {
                this.CheckMonitorModifierSet(modSet);
            }
            else
            {
                this.CheckMachineModifierSet(modSet);
            }

            var node = new MachineDeclaration(this.TokenStream.Program, parentNode, isMonitor, modSet);

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

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

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

            this.TokenStream.Swap(TokenType.MachineIdentifier);

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

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

            var nameVisitor = new NameVisitor(this.TokenStream);

            node.TemplateParameters = nameVisitor.ConsumeTemplateParams();

            if (this.TokenStream.Program is PSharpProgram)
            {
                if (this.TokenStream.Done ||
                    (this.TokenStream.Peek().Type != TokenType.Colon &&
                     this.TokenStream.Peek().Type != TokenType.LeftCurlyBracket))
                {
                    throw new ParsingException("Expected \":\" or \"{\".", this.TokenStream.Peek(), TokenType.Colon, TokenType.LeftCurlyBracket);
                }

                if (this.TokenStream.Peek().Type == TokenType.Colon)
                {
                    node.ColonToken = this.TokenStream.Peek();

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

                    var baseNameTokensVisitor = new NameVisitor(this.TokenStream, node.HeaderTokenRange);
                    node.BaseNameTokens = baseNameTokensVisitor.ConsumeGenericName(TokenType.MachineIdentifier);
                }
            }

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

            this.TokenStream.Swap(TokenType.MachineLeftCurlyBracket);

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

            this.TokenStream.Index++;
            this.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.", this.TokenStream.Peek());
            }

            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.", this.TokenStream.Peek());
            }
            else if (startStates.Count > 1)
            {
                throw new ParsingException("A machine can declare only a single start state.", this.TokenStream.Peek());
            }
        }
Пример #4
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);
            }
        }