Esempio n. 1
0
		/// <summary>
		/// Matches a <c>LastStatement</c> non-terminal.
		/// </summary>
		/// <returns><c>true</c> if the <c>LastStatement</c> was matched successfully; otherwise, <c>false</c>.</returns>
		/// <remarks>
		/// The non-terminal can start with: <c>Return</c>, <c>Break</c>.
		/// </remarks>
		protected virtual bool MatchLastStatement(BlockStatement block) {
			Statement statement = null;
			int start = this.LookAheadToken.StartOffset;
			if (!this.MatchLastStatementInner(out statement)) {
				statement = new IncompleteStatement( statement, new TextRange( start, this.Token.EndOffset ) );
			}
			if ( statement != null )
				{
				block.Statements.Add( statement );
			}
			return true;
		}
Esempio n. 2
0
		/// <summary>
		/// Matches a <c>Block</c> non-terminal.
		/// </summary>
		/// <returns><c>true</c> if the <c>Block</c> was matched successfully; otherwise, <c>false</c>.</returns>
		/// <remarks>
		/// The non-terminal can start with: <c>Do</c>, <c>While</c>, <c>Repeat</c>, <c>If</c>, <c>For</c>, <c>Local</c>, <c>Function</c>, <c>Return</c>, <c>Break</c>, <c>OpenParenthesis</c>, <c>OpenCurlyBrace</c>, <c>Identifier</c>, <c>TripleDot</c>, <c>Nil</c>, <c>False</c>, <c>True</c>, <c>Number</c>, <c>Subtraction</c>, <c>Not</c>, <c>Hash</c>, <c>String</c>.
		/// </remarks>
		protected virtual bool MatchBlock(out BlockStatement block) {
			block = new BlockStatement();
			block.StartOffset = this.LookAheadToken.StartOffset;
			if (this.IsInMultiMatchSet(0, this.LookAheadToken)) {
				this.MatchChunk(block);
			}
			block.EndOffset = this.LookAheadToken.StartOffset;
			return true;
		}
Esempio n. 3
0
		/// <summary>
		/// Matches a <c>Chunk</c> non-terminal.
		/// </summary>
		/// <returns><c>true</c> if the <c>Chunk</c> was matched successfully; otherwise, <c>false</c>.</returns>
		/// <remarks>
		/// The non-terminal can start with: <c>Do</c>, <c>While</c>, <c>Repeat</c>, <c>If</c>, <c>For</c>, <c>Local</c>, <c>Function</c>, <c>Return</c>, <c>Break</c>, <c>OpenParenthesis</c>, <c>OpenCurlyBrace</c>, <c>Identifier</c>, <c>TripleDot</c>, <c>Nil</c>, <c>False</c>, <c>True</c>, <c>Number</c>, <c>Subtraction</c>, <c>Not</c>, <c>Hash</c>, <c>String</c>.
		/// </remarks>
		protected virtual bool MatchChunk(BlockStatement block) {
			while (this.IsInMultiMatchSet(1, this.LookAheadToken)) {
				if (!this.MatchStatement(block))
					return false;
				if (this.TokenIs(this.LookAheadToken, LuatTokenId.SemiColon)) {
					this.Match(LuatTokenId.SemiColon);
				}
				block.FirstUnconsumedToken = this.LookAheadToken;
			}
			if (((this.TokenIs(this.LookAheadToken, LuatTokenId.Return)) || (this.TokenIs(this.LookAheadToken, LuatTokenId.Break)))) {
				if (!this.MatchLastStatement(block))
					return false;
				if (this.TokenIs(this.LookAheadToken, LuatTokenId.SemiColon)) {
					this.Match(LuatTokenId.SemiColon);
				}
				block.FirstUnconsumedToken = this.LookAheadToken;
			}
			return true;
		}
Esempio n. 4
0
		/// <summary>
		/// Matches a <c>CUBlock</c> non-terminal.
		/// </summary>
		/// <returns><c>true</c> if the <c>CUBlock</c> was matched successfully; otherwise, <c>false</c>.</returns>
		/// <remarks>
		/// The non-terminal can start with: <c>Do</c>, <c>While</c>, <c>Repeat</c>, <c>If</c>, <c>For</c>, <c>Local</c>, <c>Function</c>, <c>Return</c>, <c>Break</c>, <c>OpenParenthesis</c>, <c>OpenCurlyBrace</c>, <c>Identifier</c>, <c>TripleDot</c>, <c>Nil</c>, <c>False</c>, <c>True</c>, <c>Number</c>, <c>Subtraction</c>, <c>Not</c>, <c>Hash</c>, <c>String</c>.
		/// </remarks>
		protected virtual bool MatchCUBlock(out BlockStatement block) {
			block = new BlockStatement();
			block.StartOffset = 0;
			
			while( !this.IsAtEnd )
				{
				IToken prevToken      = this.Token;
				bool   bChunkError    = true;
				int    prevErrorCount = compilationUnit.SyntaxErrors.Count;
				if (this.MatchChunk(block)) {
					bChunkError = false;
				}
				// Did the Block non-terminal raise its own error message?
				bool bErrorsReported = compilationUnit.SyntaxErrors.Count > prevErrorCount;
				
				// Should we display an error for the text range of this block?
				bool bDisplayError = bChunkError && !bErrorsReported;
				
				if ( bDisplayError )
					{
					int  errorStart = ( block != null && block.FirstUnconsumedToken != null ) ? block.FirstUnconsumedToken.StartOffset : 0;
					int  errorEnd   = ( this.Token != null ) ? this.Token.EndOffset : this.LookAheadToken.EndOffset;
					
					this.ReportSyntaxError( new TextRange( errorStart, errorEnd ), "Invalid statement" );
				}
				
				if ( this.Token == prevToken )
					{
					// Token did not advance, probably due to error.
					// Move it along.
					this.AdvanceToNext();
				}
				};
				block.EndOffset = this.LookAheadToken.StartOffset;
			return true;
		}