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

📄 csparser.cs

📁 c#精彩编程百例(源代码)
💻 CS
字号:
//  CSParser.cs 
//  Copyright (c) 2000 Mike Krueger
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

using System;
using System.Collections;
using System.IO;

using SharpDevelop.Internal.Text;
using SharpDevelop.Internal.Project;

namespace SharpDevelop.Internal.Parser {
	
	public class Namespace
	{
		string  name;
		long    line;
		
		public ArrayList Namespaces = new ArrayList();
		public ArrayList Classes    = new ArrayList();
		
		public Namespace(string name, long line)
		{
			this.name = name;
			this.line = line;
		}
		
		public string Name {
			get {
				return name;
			}
		}
		
		public long Line {
			get {
				return line;
			}
		}
	}
	public enum MemberType { Class, Field, Property, Method };
	public class MemberInfo
	{
		string filename;
		string name;
		long   line;
		public MemberType    type;
		
		public MemberInfo(string filename, string name, long line)
		{
			this.filename = filename;
			this.name = name;
			this.line = line;
		}
		
		public string FileName {
			get {
				return filename;
			}
		}
		
		public string Name {
			get {
				return name;
			}
		}
		
		public long Line {
			get {
				return line;
			}
		}
	}
	
	public class Class : MemberInfo
	{
		public ArrayList Members = new ArrayList();
		public Class(string filename, string name, long line) : base(filename, name, line)
		{
			type = MemberType.Class;
		}
	}
	
	public class FileInfo
	{
		string     name;
		ArrayList  namespaces = new ArrayList();
		
		public FileInfo(string name)
		{
			this.name = name;
			namespaces.Add("");
		}
		
		public ArrayList NameSpaces {
			get {
				return namespaces;
			}
		}
		public string FileName {
			get {
				return name;
			}
		}
	}
	
	public class CSParser
	{
		public Namespace Global;
		public Hashtable FileInfos = new Hashtable();
		
		Stack Namespaces   = new Stack();
		
		string param;
		string text;
		string id;
		string filename;
		int    counter = 0;
		long   curLine = 0;
		FileInfo curFile;
		
		public CSParser()
		{}
		
		public void Parse(SharpDevelop.Internal.Project.ISdProject p)
		{
			Global    = new Namespace("GLOBAL", 0);
			FileInfos = new Hashtable();
			foreach (string file in p.Files)
				if (Path.GetExtension(file).Equals(".cs")) {
					counter = 0;
					curLine = 0;
					curFile = new FileInfo(file);
					this.filename = file;
					StreamReader s  = File.OpenText(file);
					this.text = s.ReadToEnd();
					s.Close();
					Namespaces.Clear();
					Namespaces.Push(Global);
					Program();
					FileInfos[file] = curFile;
				}
		}
		
		public void Parse(TextBuffer buffer)
		{
			counter = 0;
			curLine = 0;
			Global   = new Namespace("GLOBAL", 0);
//			this.filename = buffer.FileName;
			this.text     = buffer.Text;
			curFile = new FileInfo(filename);
			Namespaces.Push(Global);
			Program();
			FileInfos[filename] = curFile;
		}
		
		void Program()
		{
			while (counter < text.Length) 
			{
				SkipWhiteSpaces();
				ReadClassOrNamespace();
			}
		}
		
		void ReadClassMembers(Class c)
		{
			while (counter < text.Length && text[counter] != '{') {
				if (counter < text.Length && text[counter] == '/') {
					SkipDocumentation();
					continue;
				}
				if (counter < text.Length && text[counter] == '"') {
					SkipString();
					continue;
				}
				
				if (counter < text.Length && text[counter] == '\n')
					++curLine;
				++counter;
			}
			++counter;
			bool method = false;
			while (counter < text.Length) {
				if (counter < text.Length && text[counter] == '/') {
					SkipDocumentation();
					continue;
				}
				if (counter < text.Length && text[counter] == '{') {
					if (!method) {
						MemberInfo mi = new MemberInfo(filename, id, curLine);
						mi.type = MemberType.Property; // property
						c.Members.Add(mi);
					}
					SkipBlock();
					method = false;
				}
				
				if (counter < text.Length && text[counter] == '"') {
					SkipString();
					continue;
				}
				
				if (counter < text.Length && text[counter] == '(') {
					MemberInfo mi = new MemberInfo(filename, id, curLine);
					mi.type = MemberType.Method; // method
					c.Members.Add(mi);
					method = true;
					SkipBlock();
				}
				
				if (counter < text.Length && text[counter] == ';') {
					MemberInfo mi = new MemberInfo(filename, id, curLine);
					mi.type = MemberType.Field; // field
					c.Members.Add(mi);
				}
				
				if (counter < text.Length && Char.IsLetter(text[counter])) {
					ReadIdentifer();
				}
				
				if (counter < text.Length && text[counter] == '\n')
					++curLine;
				++counter;
			}
			++counter;
		
		}
		
		void ReadMembers()
		{
			while (counter < text.Length)
			{
				SkipWhiteSpaces();
				
				if (counter + 8 < text.Length && text.Substring(counter, 8).ToUpper().Equals("PROTECTED")) {
					counter += 8;
				} else 
					if (counter + 7 < text.Length && text.Substring(counter, 7).ToUpper().Equals("PRIVATE")) {
						counter += 7;
					} else 
						if (counter + 6 < text.Length && text.Substring(counter, 6).ToUpper().Equals("PUBLIC")) {
							counter += 6;
						} else 
							if (counter + 6 < text.Length && text.Substring(counter, 6).ToUpper().Equals("STATIC")) {
								counter += 6;
							} else
								if (counter + 5 < text.Length && text.Substring(counter, 5).ToUpper().Equals("CLASS")) {
									counter += 5;
									SkipWhiteSpaces();
									ReadIdentifer();
									ReadMembers();
								} else 
									if (counter < text.Length) {
										ReadIdentifer();
										string type = id;
										ReadIdentifer();
										string name = id;
										SkipWhiteSpaces();
										if (text[counter] == '{') {
												SkipBlock();
										 } else
										 	if (text[counter] == '(') {
										 		ReadParams();
										 	} else {
										 	}
										}
									}
			}
			
			void ReadClassOrNamespace()
			{
				SkipWhiteSpaces();
				bool openbracket = text[counter] == '{';
				Namespace curSpace = (Namespace)Namespaces.Peek();
				while (counter < text.Length) {
					SkipWhiteSpaces();
					
					if (counter < text.Length && text[counter] == '"') {
						SkipString();
						continue;
					}
					
					if (counter < text.Length && openbracket && text[counter] == '}') {
						SkipWhiteSpaces();
						ReadIdentifer();
					}
					
					if (counter + 5 < text.Length && text.Substring(counter, 5).ToUpper().Equals("USING")) {
						counter += 5;
						SkipWhiteSpaces();
						ReadIdentifer();
						curFile.NameSpaces.Add(id);
					} else
					if (counter + 4 < text.Length && text.Substring(counter, 4).ToUpper().Equals("ENUM")) {
						counter += 4;
						SkipWhiteSpaces();
						ReadIdentifer();
						SkipWhiteSpaces();
						SkipBlock(); // TODO : Read Enum Members
					} else
					if (counter + 9 < text.Length && text.Substring(counter, 9).ToUpper().Equals("INTERFACE")) {
						counter += 9;
						SkipWhiteSpaces();
						ReadIdentifer();
						curSpace.Classes.Add(new Class(filename, id, curLine));
						SkipWhiteSpaces();
						SkipBlock(); // TODO : Read Class Members
					} else
					if (counter + 6 < text.Length && text.Substring(counter, 6).ToUpper().Equals("STRUCT")) {
						counter += 6;
						SkipWhiteSpaces();
						ReadIdentifer();
						curSpace.Classes.Add(new Class(filename, id, curLine));
						SkipWhiteSpaces();
						SkipBlock(); // TODO : Read Class Members
					} else
					if (counter + 5 < text.Length && text.Substring(counter, 5).ToUpper().Equals("CLASS")) {
						counter += 5;
						SkipWhiteSpaces();
						ReadIdentifer();
						Class c = new Class(filename, id, curLine);
						curSpace.Classes.Add(c);
						SkipWhiteSpaces();
//						ReadClassMembers(c);
						SkipBlock(); // TODO : Read Class Members
					} else 
					if (counter + 9 < text.Length && text.Substring(counter, 9).ToUpper().Equals("NAMESPACE")) {
						counter += 9;
						SkipWhiteSpaces();
						ReadIdentifer();
						Namespace newspace = null;
						string[] namespacepath = id.Split(new char[] { '.' });
						for (int i = 0; i < namespacepath.Length; ++i) {
							Console.WriteLine(namespacepath[i]);
						}
						Console.WriteLine("----------");
						newspace = GetNamespace(Global, 0, namespacepath);
//						if (newspace == null) {
//							newspace = new Namespace(id, curLine);
//							curSpace.Namespaces.Add(newspace);
//						}
						Namespaces.Push(newspace);
						ReadClassOrNamespace();
						Namespaces.Pop();
					} else
						++counter;
				}
			}
			
			Namespace GetNamespace(Namespace node, int ptr, string[] path)
			{
				for (int i = 0; i < node.Namespaces.Count; ++i) {
					Namespace curSpace = (Namespace)node.Namespaces[i];
					if (curSpace.Name.Equals(path[ptr])) {
						++ptr;
						if (ptr >= path.Length)
							return curSpace;
						return GetNamespace(curSpace, ptr, path);
					}
				}
				node.Namespaces.Add(new Namespace(path[ptr], -1));
				return GetNamespace(node, ptr, path);
			}
			
			void ReadParams()
			{
				SkipWhiteSpaces();
				param = "";
				while (counter < text.Length && text[counter] != ')') {
					param += text[counter];
					++counter;
				}
			}
			
			void ReadIdentifer()
			{
				SkipWhiteSpaces();
				id = "";
				while (counter < text.Length && text[counter] != ';' && (Char.IsLetterOrDigit(text[counter]) || text[counter] == '_')) {
					id += text[counter];
					++counter;
				}
			}
			
			void SkipString()
			{
				++counter;
				while (counter < text.Length && text[counter] != '"') {
					if (text[counter] == '\n')
						++curLine;
					++counter;
				}
				++counter;
			}
			
			void SkipBlock()
			{
				int braces = 0;
				while (counter < text.Length && text[counter] != '{') {
					if (counter < text.Length && text[counter] == '/') {
						SkipDocumentation();
						continue;
					}
					if (counter < text.Length && text[counter] == '"') {
						SkipString();
						continue;
					}
					
					if (counter < text.Length && text[counter] == '\n')
						++curLine;
					++counter;
				}
				++counter;
				
				while (counter < text.Length) {
					if (counter < text.Length && text[counter] == '/') {
						SkipDocumentation();
						continue;
					}
					if (counter < text.Length && text[counter] == '{')
						++braces;
						
					if (counter < text.Length && text[counter] == '}') {
						--braces;
						if (braces < 0)
							break;
					}
					
					if (counter < text.Length && text[counter] == '"') {
						SkipString();
						continue;
					}
					if (counter < text.Length && text[counter] == '\n')
						++curLine;
					++counter;
				}
				++counter;
		}
		
		void SkipDocumentation()
		{
			++counter;
			if (counter >= text.Length)
				return;
			
			if (text[counter] == '/') {  // line comment
				while (counter < text.Length && text[counter] != '\n')
					++counter;
				return;
			}
			if (text[counter] == '*') {  // block comment
				while (counter + 1 < text.Length && text[counter] != '*' && text[counter + 1] != '/') {
					if (text[counter] == '\n')
						++curLine;
					++counter;
				}
				counter += 2;
				return;
			}
		}
		
		void SkipWhiteSpaces()
		{
			while (counter < text.Length && Char.IsWhiteSpace(text[counter])) {
				if (text[counter] == '\n')
					++curLine;
				++counter;
			}
			if (counter < text.Length  && text[counter] == '/') {
				SkipDocumentation();
				SkipWhiteSpaces();
			}
		}
	}
}

⌨️ 快捷键说明

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