using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public enum types
{
KeyID=1,ParID,Ints,Operator,Split,Floats,ElseID//类型的枚举类型的定义
}
//用来存放识别出的单词
public class IDS
{
public types type;//类型
public string data;//值
public IDS next;//指向下一个IDS的指针
}
public class AccidenceAnalyse
{
#region 成员变量
public char[] AllChars;
/// <summary>
/// 全局变量指针,指向当前字符
/// </summary>
private int CurrentP;
private StringBuilder ResultStr;
private int _KeyIDnum = 0;
private int _ParIDnum = 0;
private int _IntNum = 0;
private int _FloatNum = 0;
private int _SplitNum = 0;
private int _OperatorNum = 0;
public int _ElseNum = 0;
private int _AllNum = 0;
public int AllNum
{ get { return _AllNum; } }
public int KeyIDnum
{
get { return _KeyIDnum;}
}
public int ParIDnum
{
get { return _ParIDnum;}
}
public int FloatNum
{ get { return _FloatNum; } }
public int IntNum
{ get { return _IntNum; } }
public int SplitNum
{ get { return _SplitNum; } }
public int OperatorNum
{ get { return _OperatorNum; } }
public int ElseNum
{ get { return _ElseNum; } }
public IDS KeyID_Identify;//保留字
public IDS ParID_Identify;//普通标识符
public IDS Ints_Identify;//无符号整数
public IDS Operator_Identify;//运算符
public IDS Split_Identify;//分隔符
public IDS Floats_Identify;//小数
public IDS ElseID_Identify;
public IDS HeaderLink;//头指针
public IDS TailLink;//尾指针
private char[] tempch;
#endregion
/// <summary>
/// 默认构造函数
/// </summary>
public AccidenceAnalyse()
{
AllChars = null; CurrentP = 0;//指向当前字符串中第一个字符
_KeyIDnum = 0; _ParIDnum = 0; _IntNum = 0; _FloatNum = 0;
_OperatorNum = 0; _SplitNum = 0; _ElseNum = 0;
KeyID_Identify = new IDS(); KeyID_Identify.next = null;
ParID_Identify = new IDS(); ParID_Identify.next = null;
Ints_Identify = new IDS(); Ints_Identify.next = null;
Operator_Identify = new IDS(); Operator_Identify.next = null;
Split_Identify = new IDS(); Split_Identify.next = null;
Floats_Identify = new IDS(); Floats_Identify.next = null;
ElseID_Identify = new IDS(); ElseID_Identify.next = null;
HeaderLink = new IDS(); HeaderLink.next = null;
TailLink = HeaderLink;
tempch = new char[50];
ResultStr =new StringBuilder ();
}
/// <summary>
/// 带参数的构造函数
/// </summary>
/// <param name="_chars">参数char[]</param>
public AccidenceAnalyse(char[] _chars)
: this()
{
AllChars = _chars;
}
/// <summary>
/// 关键字集合,按字母排序
/// </summary>
private static string[] KeyWords = {"auto","break","case","char","const","continue",
"default","do","double","else","enum","extern",
"float","for", "goto","if","int","long","register",
"return","short","signed","sizeof","static","struct",
"switch","typedef","union","unsigned","void","volatile","while"
};
private static char [] SplitChar={',',';','{','}','(',')','/"','/'','[',']','//'};
private static char[] OperatorChar = {'+','-','*','/','%','=','<','>' };
public char[] StrToChar(string srcStr)
{
return srcStr.ToCharArray();
}
public string CharToStr(char[] srcChar)
{
return srcChar.ToString();
}
/// <summary>
/// 判断一个字符串是不是关键字
/// </summary>
/// <param name="srcStr">待判断的字符串</param>
/// <returns>如果是关键字则返回true,否则返回false</returns>
private bool IsKeyWord(string srcStr)
{//此处需要改进,应该选用效率较高的折半查找或其他效率更高的查找方法
if (srcStr != null && srcStr != "")
{
int low = 0, high = 31, mid = 15; bool flag=false;
while (low < high)
{
if (KeyWords[mid].CompareTo (srcStr)>0)
high = mid - 1;
else if (KeyWords[mid] .CompareTo (srcStr)<0)
low = mid + 1;
else break;
mid = (low + high) / 2;
}
if (KeyWords[mid] == srcStr)
flag = true;
return flag;
}
return false;
}
private bool IsNumberic()
{//判断当前字符是否为数字
return IsNumberic(AllChars[CurrentP]);
}
private bool IsNumberic(char ch)
{//判断给定字符是否为数字
if (ch >= '0' && ch <= '9')
return true;
return false;
}
private bool IsChar()
{//判断当前字符是否为字符
if ((AllChars[CurrentP] >= 'a' && AllChars[CurrentP] <= 'z')||(AllChars[CurrentP] >= 'A' && AllChars[CurrentP] <= 'Z'))
return true;
return false;
}
private bool IsUnderline()
{//判断当前字符是否为下划线
if (AllChars[CurrentP] == '_') return true;
return false;
}
private bool IsSplitChar()
{//判断是否为分隔符
bool flag=false;
foreach (char ch in SplitChar)
{
if (AllChars[CurrentP]==ch )
{ flag = true; break;}
}
return flag;
}
/// <summary>
/// 取得当前字符的前一个字符
/// </summary>
/// <param name="i">当前字符的下标</param>
/// <returns>返回下标为i-1的字符</returns>
private char GetPreChar(int i)
{
if (i>0&&i<AllChars .Length +1)
return AllChars[i - 1];
return ' ';
}
/// <summary>
/// 取得当前字符的后一个字符
/// </summary>
/// <param name="i">当前字符的下标</param>
/// <returns>返回下标为i+1的字符</returns>
private char GetBacChar(int i)
{
return AllChars[i + 1];
}
/// <summary>
/// 移动CurrentP直到遇见第一个非空格换行的字符,用来过滤程序前所有的换行与回车
/// </summary>
private void GetChar()
{
if (CurrentP < AllChars.Length)
while (CurrentP <AllChars .Length &&(AllChars[CurrentP] == ' '||AllChars [CurrentP]=='/r'||AllChars [CurrentP]=='/n'||AllChars[CurrentP]=='/t'))
GetNextChar();
}
private void DefaultChar()
{
while (AllChars[CurrentP] == ' ' || AllChars[CurrentP] == '/r' || AllChars[CurrentP] == '/n' || AllChars[CurrentP] == '/t')
{
GetNextChar();
if (CurrentP < AllChars.Length) break;
}
}
/// <summary>
/// 将指针向下移动一个位置
/// </summary>
private void GetNextChar()
{
CurrentP++;
}
private void IDAnalyse()
{
int p = 0;
do{
tempch[p++] = AllChars[CurrentP];
GetNextChar();
if(CurrentP >=AllChars .Length )break ;
}while((IsChar()||IsNumberic()||IsUnderline()));
tempch[p] = '/0';
string tempstring = new string(tempch, 0, p);
types temptype;
if (IsKeyWord(tempstring))
temptype = types.KeyID;
else
temptype = types.ParID;
AppendNodeByType(temptype, tempstring);
}
private void NumAnalyse()
{
int p = 0; types temptype = types.Ints;
do
{
tempch[p++] = AllChars[CurrentP];
GetNextChar();
if (CurrentP >= AllChars.Length) break;
} while ( IsNumberic());
if (AllChars[CurrentP] == '.'&& IsNumberic( GetBacChar(CurrentP)))
{
do
{
tempch[p++] = AllChars[CurrentP];
GetNextChar();
} while (CurrentP < AllChars.Length && IsNumberic());
temptype = types.Floats;
}
tempch[p] = '/0';
string tempstring = new string(tempch ,0,p);
AppendNodeByType(temptype , tempstring);
}
private void OperatorAnalyse()
{
int p = 0;
string tempstring = null;
switch (AllChars[CurrentP])
{
case '+':
do
{
tempch[p++] = AllChars[CurrentP]; GetNextChar();
if (CurrentP >= AllChars.Length) break;
} while (AllChars[CurrentP] == '=' || AllChars[CurrentP] == '+');
CurrentP--;
tempch[p] = '/0';
tempstring = new string(tempch, 0, p);
break;
case '-':
do
{
tempch[p++] = AllChars[CurrentP]; GetNextChar();
if (CurrentP >= AllChars.Length) break;
} while ( AllChars[CurrentP] == '=' || AllChars[CurrentP] == '-');
CurrentP--;
tempch[p] = '/0';
tempstring = new string(tempch, 0, p);
break;
case '*':
case '=':
case '%':
case '!':
case '^':
case '/':
do
{
tempch[p++] = AllChars[CurrentP]; GetNextChar();
if (CurrentP >= AllChars.Length) break;
} while (AllChars[CurrentP] == '=');
CurrentP--;
tempch[p] = '/0';
tempstring = new string(tempch, 0, p);
break;
case '~':
tempstring = new string(AllChars[CurrentP], 1);
break;
case '|':
do
{
tempch[p++] = AllChars[CurrentP]; GetNextChar();
if (CurrentP >= AllChars.Length) break;
} while ( AllChars[CurrentP] == '=' || AllChars[CurrentP] == '|');
CurrentP--;
tempch[p] = '/0';
tempstring = new string(tempch, 0, p);
break;
case '>':
do
{
tempch[p++] = AllChars[CurrentP]; GetNextChar();
if (CurrentP >= AllChars.Length) break;
} while ( AllChars[CurrentP] == '=' || AllChars[CurrentP] == '>');
CurrentP--;
tempch[p] = '/0';
tempstring = new string(tempch, 0, p);
break;
case '<':
do
{
tempch[p++] = AllChars[CurrentP]; GetNextChar();
if (CurrentP >= AllChars.Length) break;
} while ( AllChars[CurrentP] == '=' || AllChars[CurrentP] == '<');
CurrentP--;
tempch[p] = '/0';
tempstring = new string(tempch, 0, p);
break;
case '&':
do
{
tempch[p++] = AllChars[CurrentP]; GetNextChar();
if (CurrentP >= AllChars.Length) break;
} while (AllChars[CurrentP] == '=' || AllChars[CurrentP] == '&');
CurrentP--;
tempch[p] = '/0';
tempstring = new string(tempch, 0, p);
break;
}
if (tempstring != null)
AppendNodeByType(types.Operator, tempstring);
}
/// <summary>
/// //分析参数字符串,例如分析语句 char *p="string" 中的string
/// </summary>
private void ParStringAnalyse()
{
int p=0;
if (AllChars[CurrentP] == '/"')
{
do
{
tempch[p++] = AllChars[CurrentP]; GetNextChar();
} while (CurrentP < AllChars.Length && AllChars[CurrentP] != '/"');
tempch[p] = '/0';
string tempstring = new string(tempch, 0, p);
AppendNodeByType(types.ElseID, tempstring);
}
}
/// <summary>
/// 将分析得到的单词添加到对应的链表中
/// </summary>
/// <param name="_type">单词的类型</param>
/// <param name="_data">单词的值</param>
private void AppendNodeByType(types _type, string _data)
{
IDS temp = new IDS(); temp.next = null;
temp.data = _data; temp.type = _type;
switch (_type)
{
case types.KeyID:
_KeyIDnum++; temp.next = KeyID_Identify.next;
KeyID_Identify.next = temp;
break;
case types.ParID:
_ParIDnum++; temp.next = ParID_Identify.next;
ParID_Identify.next = temp;
break;
case types.Ints:
_IntNum++;
temp.next = Ints_Identify.next;
Ints_Identify.next = temp;
break;
case types.Floats:
_FloatNum++; temp.next = Floats_Identify.next;
Floats_Identify.next = temp;
break;
case types.Operator:
_OperatorNum++; temp.next = Operator_Identify.next;
Operator_Identify.next = temp;
break;
case types.Split:
_SplitNum++; temp.next = Split_Identify.next;
Split_Identify.next = temp;
break;
case types.ElseID:
_ElseNum++; temp.next = ElseID_Identify.next;
ElseID_Identify.next = temp;
break;
default :
break;
}
_AllNum++; TailLink.next = temp; TailLink = temp;
}
private void AppendNode(types _type, string _data)
{
}
/// <summary>
/// 按类返回分析的结果字符串
/// </summary>
/// <returns>分析结果字符串</returns>
public string ReturnResultsByType()
{
ResultStr.AppendLine("普通标识符如下(总数" + _ParIDnum + "):");
PrintOneResult (ParID_Identify,_ParIDnum); ;
ResultStr.AppendLine("关键字如下(总数" + _KeyIDnum + "):");
PrintOneResult(KeyID_Identify, _KeyIDnum);
ResultStr.AppendLine("整型数字如下(总数" + _IntNum + "):");
PrintOneResult(Ints_Identify, _IntNum);
ResultStr.AppendLine("浮点数字如下(总数" + _FloatNum + "):");
PrintOneResult(Floats_Identify, _FloatNum);
ResultStr.AppendLine("分隔符如下(总数" + _SplitNum + "):");
PrintOneResult(Split_Identify, _SplitNum);
ResultStr.AppendLine("操作符如下(总数" + _OperatorNum + "):");
PrintOneResult(Operator_Identify, _OperatorNum);
ResultStr.AppendLine("其他如下(总数" + _ElseNum + "):");
PrintOneResult(ElseID_Identify, _ElseNum);
return ResultStr.ToString ();
}
public string ReturnAllresults()
{
ResultStr.AppendLine("分析结果如下:");
PrintOneResult(HeaderLink, _AllNum);
return ResultStr.ToString ();
}
private void PrintOneResult(IDS Header, int number)
{
for (int i = 0; i < number; i++)
{
Header = Header.next;
ResultStr .Append("(" + ((int)Header.type).ToString() + "," + Header.data + ") /r/n ");
}
}
public void Analyse()
{
GetChar();//将指针移动到程序的第一个字符
while (CurrentP < AllChars.Length)
{
if (AllChars[CurrentP] == '/' && GetBacChar(CurrentP) == '*')//注释的开始
{
do
{//将注释略过,不分析
GetNextChar();
} while (CurrentP < AllChars.Length && !(AllChars[CurrentP] == '/' && (GetPreChar(CurrentP) == '*')));
GetNextChar();//将最后读取到的'/'字符掠过
}
// ParStringAnalyse();
if (CurrentP >= AllChars.Length)
break;
if (CurrentP <AllChars .Length&&IsChar() )
{
IDAnalyse();
}
if (CurrentP < AllChars.Length && IsNumberic())
{
NumAnalyse();
}
if (CurrentP < AllChars.Length && IsSplitChar())
{
string tempstring = new string(AllChars[CurrentP], 1);
AppendNodeByType(types.Split, tempstring);
}
if (CurrentP <AllChars .Length )
OperatorAnalyse();
GetNextChar();
}
}
}
}