?? 詞法分析.cs
字號:
?using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
namespace 詞法分析
{
class 詞法分析
{
private int rnum;//行號
private int rpos;//列號
private static ArrayList symbolTable;
private StreamReader br;
private char c;
private char bC;
private int state;
private String str;
//構造函數
public 詞法分析(StreamReader br)
{
symbolTable = new ArrayList();
this.br=br;
c=' ';
bC=' ';
state = 0;
rnum=1;
rpos=0;
str="";
}
//返回字符數組
public ArrayList getSymbolTable()
{
c = nextChar();
state = 0;
analyzer();
return symbolTable;
}
//主體函數
private void analyzer()
{
bool isRunning=true;
while(isRunning)
{
switch (state)
{
case 0:
if(c==' ') //空格
{
}
else if(c=='\t') //tab
{
rpos+=3;
}
else if((int)c==13) //空格
{
}
else if((int)c==10) //回車
{
rpos = 0;
rnum++;
}
else if(c=='~') //結束符
{
return;
}
else if(c=='+') //操作符+
{
install("運算符", "+", rpos, rnum);
}
else if(c=='-') //操作符-
{
install("運算符", "-", rpos, rnum);
}
else if(c=='/') //操作符/
{
state = 1;
}
else if(c=='*') //操作符*
{
install("運算符", "*", rpos, rnum);
}
else if(c=='=') //操作符=
{
state = 2;
}
else if(c=='<') //操作符<
{
state = 3;
}
else if(c=='>') //操作符>
{
state = 4;
}
else if(c=='!') //操作符!
{
state = 5;
}
else if(c=='{') //分隔符{
{
install("分隔符","{",rpos,rnum);
}
else if(c=='}') //分隔符}
{
install("分隔符","}",rpos,rnum);
}
else if(c=='(') //分隔符(
{
install("分隔符","(",rpos,rnum);
}
else if(c==')') //分隔符)
{
install("分隔符",")",rpos,rnum);
}
else if(c==';') //分隔符;
{
install("分隔符",";",rpos,rnum);
}
else if((int)c==65535)
{
isRunning=false;
}
else if(character(c)) //讀到了字符
{
bC = c;
state = 6;
}
else if(digit(c)) //讀到了數字符
{
bC = c;
str="";
state = 7;
}
else if(c=='#')
{
state=13;
}
else
{
state=0;
isRunning=false;
fail(0);
}
c = nextChar();
break;
case 1:
if(c=='/') //表示注釋后面的東西,不讀它
{
while((int)c!=10)
{
c = nextChar();
}
rpos=0; //從下一行開始
rnum++;
c = nextChar();
state = 0;
}
else
{
state = 0; // 下一個不是/, 后退一步到state=0
install("運算符", "/", rpos - 1, rnum);
}
break;
case 2:
if(c=='=') //表示操作符==
{
state = 0;
install("運算符", "==", rpos - 1, rnum);
c = nextChar();
}
else
{
state = 0;
install("運算符", "=", rpos - 1, rnum);
}
break;
case 3:
if(c=='=') //表示操作符<=
{
state = 0;
install("運算符", "<=", rpos - 1, rnum);
c = nextChar();
}
else
{
state = 0;
install("運算符", "<", rpos - 1, rnum);
}
break;
case 4:
if(c=='=') //表示操作符>=
{
state = 0;
install("運算符", ">=", rpos - 1, rnum);
c = nextChar();
}
else
{
state = 0;
install("運算符", ">", rpos - 1, rnum);
}
break;
case 5:
if(c=='=') // 表示操作符!=
{
state = 0;
install("運算符","!=",rpos-1,rnum);
c = nextChar();
}
else
{
state = 0;
isRunning=false;
fail(1);
}
break;
//讀入標識符,后面是 數字符和字母才是對的
case 6:
String id = ""+bC;
while(character(c)||digit(c))
{
id+=c;
c = nextChar();
}
if(Keyword(id))
install("保留字",id,rpos-id.Length,rnum);
else
install("標識符",id,rpos-id.Length,rnum);
state = 0;
break;
//讀入數字符,后面是 數字符(循環); .(轉狀態);E(轉狀態)
case 7:
str+=bC;
while(digit(c))
{
str+=c;
c=nextChar();
}
if(c=='.')
{
state=8;
c=nextChar();
}
else if(c=='E')
{
state=10;
c=nextChar();
}
//需要判斷是否是 11w等
else if(character(c))
{
state = 0;
isRunning=false;
fail(4);
}
else
{
state = 0;
install("常數",str,rpos-str.Length,rnum);
}
break;
// " ." 后面跟的字符,除了數字符其它都出錯
case 8:
str+='.';
if(digit(c))
{
state = 9;
str+=c;
c=nextChar();
}
else
{
state = 0;
isRunning=false;
fail(2);
}
break;
// ".數字符" 后面字符,可以是數字符或者是E(需要加錯誤提示,當不是空格而是其他字母時候)
case 9:
while(digit(c))
{
str+=c;
c=nextChar();
}
if(c=='E')
{
state = 10;
c=nextChar();
}
//需要判斷是否是 11w 等
else if(character(c))
{
state = 0;
isRunning=false;
fail(2);
}
else
{
state = 0;
install("常數",str,rpos-str.Length,rnum);
}
break;
// "E" 后面字符, "+";"-";"數字符" 都是對的,其他都是錯的
case 10:
str+='E';
if(c=='+'||c=='-')
{
state=11;
str+=c;
c=nextChar();
}
else if(digit(c))
{
state=12;
str+=c;
c=nextChar();
}
else
{
state=0;
isRunning=false;
fail(2);
}
break;
// "+" "-" 后面字符, 數字符是對的.其他都是錯的
case 11:
if(digit(c))
{
state=12;
str+=c;
c=nextChar();
}
else
{
state = 0;
isRunning=false;
fail(2);
}
break;
// "E數字符" 后面字符,只有數字符是對的
case 12:
while(digit(c))
{
str+=c;
c=nextChar();
}
if(character(c))
{
state = 0;
isRunning=false;
fail(2);
}
install("常數",str,rpos-str.Length,rnum);
state=0;
break;
case 13: //聲明部分
id ="#";
while(character(c))
{
id+=c;
c = nextChar();
}
if(id=="#include"&&c=='<')
{
id+=c;
c = nextChar();
while(character(c)||this.digit(c))
{
id+=c;
c = nextChar();
}
if(c=='>')
{
id+=c;
install("文件引入",id,rpos-id.Length,rnum);
c = nextChar();
}
else
fail(3);
}
else
fail(0);
state = 0;
break;
}
}
}
//判斷字節流中字符不合法,輸出錯誤信息
private void fail(int i)
{
string typeerror="";;
switch(i)
{
case 0:
typeerror="輸入非法字符錯誤";
break;
case 1:
typeerror="操作符錯誤";
break;
case 2:
typeerror="數字符錯誤";
break;
case 3:
typeerror="聲明錯誤";
break;
case 4:
typeerror="標識符錯誤";
break;
}
Console.Write(typeerror+",位置<"+rnum+","+rpos+">");
}
//判斷下一個字符
private char nextChar()
{
char t;
rpos++;
if(br.Peek() == -1)
{
br.Close();
return '~';
}
t= (char) br.Read();
return t;
}
//輸出字節流中每個字符的信息,包括行號,列號(主要的輸出函數)
private void install(String tType,String aValue,int rpos,int rnum)
{
ArrayList tokenArray = new ArrayList();
tokenArray.Add(tType);
if (tType == "保留字")
tokenArray.Add("種別碼" + "1");
if (tType == "標識符")
tokenArray.Add("種別碼" + "2");
if (tType == "常數")
tokenArray.Add(" " + "種別碼" + "3");
if (tType == "運算符")
tokenArray.Add("種別碼" + "4");
if (tType == "分隔符")
tokenArray.Add("種別碼" + "5");
tokenArray.Add(aValue);
tokenArray.Add("<"+rnum.ToString()+","+rpos.ToString()+">");
symbolTable.Add(tokenArray);
ArrayList tempArray=tokenArray;
for(int j=0;j<tempArray.Count;j++)
{
Console.Write(tempArray[j].ToString()+" ");
}
Console.WriteLine();
str="";
}
//判斷是否是字母
private bool character(char checkChar)
{
int checkInt = (int)checkChar;
if((checkInt<=122&&checkInt>=97)||(checkInt>=65&&checkInt<=97))
{
return true;
}
return false;
}
//判斷是否是數字
private bool digit(char checkChar)
{
int checkInt = (int)checkChar;
if(checkInt<=57&&checkInt>=48)
{
return true;
}
return false;
}
//判斷是否是保留字(關鍵字)
private bool Keyword(String checkKey)
{
if(checkKey.Equals("if")||checkKey.Equals("then")||
checkKey.Equals("else")||checkKey.Equals("int")||
checkKey.Equals("for")||checkKey.Equals("while"))
{
return true;
}
return false;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -