⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csharpparser.cs

📁 根据cs源码解析为codedom
💻 CS
📖 第 1 页 / 共 2 页
字号:
// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
//     <version>$Revision: 2638 $</version>
// </file>

using System;
using System.Collections.Generic;
using System.Text;

using ICSharpCode.NRefactory.Ast;

namespace ICSharpCode.NRefactory.Parser.CSharp
{
	internal sealed partial class Parser : AbstractParser
	{
		Lexer lexer;
		
		public Parser(ILexer lexer) : base(lexer)
		{
			this.lexer = (Lexer)lexer;
		}
		
		StringBuilder qualidentBuilder = new StringBuilder();

		Token t {
			[System.Diagnostics.DebuggerStepThrough]
			get {
				return lexer.Token;
			}
		}

		Token la {
			[System.Diagnostics.DebuggerStepThrough]
			get {
				return lexer.LookAhead;
			}
		}

		public void Error(string s)
		{
			if (errDist >= MinErrDist) {
				this.Errors.Error(la.line, la.col, s);
			}
			errDist = 0;
		}

		public override Expression ParseExpression()
		{
			lexer.NextToken();
			Expression expr;
			Expr(out expr);
			// SEMICOLON HACK : without a trailing semicolon, parsing expressions does not work correctly
			if (la.kind == Tokens.Semicolon) lexer.NextToken();
			Expect(Tokens.EOF);
			return expr;
		}
		
		public override BlockStatement ParseBlock()
		{
			lexer.NextToken();
			compilationUnit = new CompilationUnit();
			
			BlockStatement blockStmt = new BlockStatement();
			blockStmt.StartLocation = la.Location;
			compilationUnit.BlockStart(blockStmt);
			
			while (la.kind != Tokens.EOF) {
				Token oldLa = la;
				Statement();
				if (la == oldLa) {
					// did not advance lexer position, we cannot parse this as a statement block
					return null;
				}
			}
			
			compilationUnit.BlockEnd();
			Expect(Tokens.EOF);
			return blockStmt;
		}
		
		public override List<INode> ParseTypeMembers()
		{
			lexer.NextToken();
			compilationUnit = new CompilationUnit();
			
			TypeDeclaration newType = new TypeDeclaration(Modifiers.None, null);
			compilationUnit.BlockStart(newType);
			ClassBody();
			compilationUnit.BlockEnd();
			Expect(Tokens.EOF);
			return newType.Children;
		}
		
		// Begin ISTypeCast
		bool IsTypeCast()
		{
			if (la.kind != Tokens.OpenParenthesis) {
				return false;
			}
			if (IsSimpleTypeCast()) {
				return true;
			}
			return GuessTypeCast();
		}

		// "(" ( typeKW [ "[" {","} "]" | "*" ] | void  ( "[" {","} "]" | "*" ) ) ")"
		// only for built-in types, all others use GuessTypeCast!
		bool IsSimpleTypeCast ()
		{
			// assert: la.kind == _lpar
			lexer.StartPeek();
			Token pt = lexer.Peek();
			
			if (!IsTypeKWForTypeCast(ref pt)) {
				return false;
			}
			if (pt.kind == Tokens.Question)
				pt = lexer.Peek();
			return pt.kind == Tokens.CloseParenthesis;
		}

		/* !!! Proceeds from current peek position !!! */
		bool IsTypeKWForTypeCast(ref Token pt)
		{
			if (Tokens.TypeKW[pt.kind]) {
				pt = lexer.Peek();
				return IsPointerOrDims(ref pt) && SkipQuestionMark(ref pt);
			} else if (pt.kind == Tokens.Void) {
				pt = lexer.Peek();
				return IsPointerOrDims(ref pt);
			}
			return false;
		}

		/* !!! Proceeds from current peek position !!! */
		bool IsTypeNameOrKWForTypeCast(ref Token pt)
		{
			if (IsTypeKWForTypeCast(ref pt))
				return true;
			else
				return IsTypeNameForTypeCast(ref pt);
		}

		// TypeName = ident [ "::" ident ] { ["<" TypeNameOrKW { "," TypeNameOrKW } ">" ] "." ident } ["?"] PointerOrDims
		/* !!! Proceeds from current peek position !!! */
		bool IsTypeNameForTypeCast(ref Token pt)
		{
			// ident
			if (pt.kind != Tokens.Identifier) {
				return false;
			}
			pt = Peek();
			// "::" ident
			if (pt.kind == Tokens.DoubleColon) {
				pt = Peek();
				if (pt.kind != Tokens.Identifier) {
					return false;
				}
				pt = Peek();
			}
			// { ["<" TypeNameOrKW { "," TypeNameOrKW } ">" ] "." ident }
			while (true) {
				if (pt.kind == Tokens.LessThan) {
					do {
						pt = Peek();
						if (!IsTypeNameOrKWForTypeCast(ref pt)) {
							return false;
						}
					} while (pt.kind == Tokens.Comma);
					if (pt.kind != Tokens.GreaterThan) {
						return false;
					}
					pt = Peek();
				}
				if (pt.kind != Tokens.Dot)
					break;
				pt = Peek();
				if (pt.kind != Tokens.Identifier) {
					return false;
				}
				pt = Peek();
			}
			// ["?"]
			if (pt.kind == Tokens.Question) {
				pt = Peek();
			}
			if (pt.kind == Tokens.Times || pt.kind == Tokens.OpenSquareBracket) {
				return IsPointerOrDims(ref pt);
			}
			return true;
		}

		// "(" TypeName ")" castFollower
		bool GuessTypeCast ()
		{
			// assert: la.kind == _lpar
			StartPeek();
			Token pt = Peek();

			if (!IsTypeNameForTypeCast(ref pt)) {
				return false;
			}
			
			// ")"
			if (pt.kind != Tokens.CloseParenthesis) {
				return false;
			}
			// check successor
			pt = Peek();
			return Tokens.CastFollower[pt.kind] || (Tokens.TypeKW[pt.kind] && lexer.Peek().kind == Tokens.Dot);
		}
		// END IsTypeCast

		/* Checks whether the next sequences of tokens is a qualident *
		 * and returns the qualident string                           */
		/* !!! Proceeds from current peek position !!! */
		bool IsQualident(ref Token pt, out string qualident)
		{
			if (pt.kind == Tokens.Identifier) {
				qualidentBuilder.Length = 0; qualidentBuilder.Append(pt.val);
				pt = Peek();
				while (pt.kind == Tokens.Dot || pt.kind == Tokens.DoubleColon) {
					pt = Peek();
					if (pt.kind != Tokens.Identifier) {
						qualident = String.Empty;
						return false;
					}
					qualidentBuilder.Append('.');
					qualidentBuilder.Append(pt.val);
					pt = Peek();
				}
				qualident = qualidentBuilder.ToString();
				return true;
			}
			qualident = String.Empty;
			return false;
		}

		/* Skips generic type extensions */
		/* !!! Proceeds from current peek position !!! */

		/* skip: { "*" | "[" { "," } "]" } */
		/* !!! Proceeds from current peek position !!! */
		bool IsPointerOrDims (ref Token pt)
		{
			for (;;) {
				if (pt.kind == Tokens.OpenSquareBracket) {
					do pt = Peek();
					while (pt.kind == Tokens.Comma);
					if (pt.kind != Tokens.CloseSquareBracket) return false;
				} else if (pt.kind != Tokens.Times) break;
				pt = Peek();
			}
			return true;
		}

		/* Return the n-th token after the current lookahead token */
		void StartPeek()
		{
			lexer.StartPeek();
		}

		Token Peek()
		{
			return lexer.Peek();
		}

		Token Peek (int n)
		{
			lexer.StartPeek();
			Token x = la;
			while (n > 0) {
				x = lexer.Peek();
				n--;
			}
			return x;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -