📄 lexical.cs
字号:
using System;
using System.IO;
using System.Collections;
namespace Syntax_Analyzer
{
/// <summary>
/// Lexical 的摘要说明。
/// </summary>
public class Lexical
{
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 Lexical(StreamReader br)
{
symbolTable = new ArrayList();
this.br=br;
c=' ';
bC=' ';
state = 0;
rnum=1;
rpos=0;
str="";
}
public ArrayList getSymbolTable()
{
c = nextChar();
state = 0;
Console.WriteLine("-----------------------------词法分析开始---------------------------------\n");
analyzer();
Console.WriteLine("-----------------------------词法分析结束---------------------------------\n");
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(isLetter(c)) //读到了字符
{
bC = c;
state = 6;
}
else if(isDigit(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(isLetter(c)||isDigit(c))
{
id+=c;
c = nextChar();
}
if(isKey(id))
install("关键字",id,rpos-id.Length,rnum);
else
install("标识符",id,rpos-id.Length,rnum);
state = 0;
break;
//*********************************************
//读入数字符,后面是 数字符(循环); .(转状态);E(转状态)
//**********************************************
case 7:
str+=bC;
while(isDigit(c))
{
str+=c;
c=nextChar();
}
if(c=='.')
{
state=8;
c=nextChar();
}
else if(c=='E')
{
state=10;
c=nextChar();
}
//需要判断是否是 11w等
else if(isLetter(c))
{
state = 0;
isRunning=false;
fail(4);
}
else
{
state = 0;
install("数字符",str,rpos-str.Length,rnum);
}
break;
//***********************************
// " ." 后面跟的字符,除了数字符其它都出错
//***********************************
case 8:
str+='.';
if(isDigit(c))
{
state = 9;
str+=c;
c=nextChar();
}
else
{
state = 0;
isRunning=false;
fail(2);
}
break;
//***********************************************************************************
// ".数字符" 后面字符,可以是数字符或者是E(需要加错误提示,当不是空格而是其他字母时候)
//************************************************************************************
case 9:
while(isDigit(c))
{
str+=c;
c=nextChar();
}
if(c=='E')
{
state = 10;
c=nextChar();
}
//需要判断是否是 11w 等
else if(isLetter(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(isDigit(c))
{
state=12;
str+=c;
c=nextChar();
}
else
{
state=0;
isRunning=false;
fail(2);
}
break;
//*****************************************
// "+" "-" 后面字符, 数字符是对的.其他都是错的
//*****************************************
case 11:
if(isDigit(c))
{
state=12;
str+=c;
c=nextChar();
}
else
{
state = 0;
isRunning=false;
fail(2);
}
break;
//***********************************
// "E数字符" 后面字符,只有数字符是对的
//*********************************
case 12:
while(isDigit(c))
{
str+=c;
c=nextChar();
}
if(isLetter(c))
{
state = 0;
isRunning=false;
fail(2);
}
install("数字符",str,rpos-str.Length,rnum);
state=0;
break;
case 13: //声明部分
id ="#";
while(isLetter(c))
{
id+=c;
c = nextChar();
}
if(id=="#include"&&c=='<')
{
id+=c;
c = nextChar();
while(isLetter(c)||this.isDigit(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+">");
Console.WriteLine();
}
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);
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 isLetter(char checkChar)
{
int checkInt = (int)checkChar;
if((checkInt<=122&&checkInt>=97)||(checkInt>=65&&checkInt<=97))
{
return true;
}
return false;
}
private bool isDigit(char checkChar)
{
int checkInt = (int)checkChar;
if(checkInt<=57&&checkInt>=48)
{
return true;
}
return false;
}
private bool isKey(String checkKey)
{
if(checkKey.Equals("if")||checkKey.Equals("then")||
checkKey.Equals("else")||checkKey.Equals("int")||
checkKey.Equals("real")||checkKey.Equals("while"))
{
return true;
}
return false;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -