📄 analyser.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
using System.Windows.Forms;
namespace accidenceAnalyser
{
/*
* 主程序即后台处理程序。
*/
class Analyser
{
//按值排列自定义
public const int ENDFILE = -1;
private const int END = -1;
public const int ERROR = -2;
public const int IF = -3;
public const int ELSE = -4;
public const int WHILE = -5;
public const int REAL = -6;
public const int READ = -7;
public const int WRITE = -8;
public const int INTEGER = -9;
public const int CHAR = -10;
public const int ID = -11;
public const int NUM = -12;
public const int CHARC = -13;
public const int ASSIGN = -14;
public const int EQ = -15;
public const int LT = -16;
public const int GT = -17;
public const int PLUS = -18;
public const int MINUS = -19;
public const int TIMES = -20;
public const int OVER = -21;
public const int LPAREN = -22;
public const int RPAREN = -23;
public const int LBRACE = -24;
public const int RBRACE = -25;
public const int DOT = -26;
public const int SymbolI = -27;
public const int COMMA = -28;
public const int LMIDPAREN = -29;
public const int RMIDPAREN = -30;
public const int UNDERANGE = -31;
private const int LCOMMENT = -32;
private const int RCOMMENT = -33;
//字符输入流
private StringReader reader;
//生成的Token序列
private Queue<Tokenizer> tokenList;
//分析结果
private string output = "";
//分行读入的字符串
private string lineBuf;
//行,列位置
private int lineNum, linePos;
//错误信息
private ErrorList errorList;
private Queue<int> errorLines = new Queue<int>();
//当前处理单词的Token
private Tokenizer cToken = new Tokenizer();
//当前处理的单词
private String cChar = "";
//保留字列表
private KeyWord[] keyWord = new KeyWord[] {
new KeyWord("int",INTEGER),
new KeyWord("char", CHAR),
new KeyWord("if", IF),
new KeyWord("else", ELSE),
new KeyWord("read",READ),
new KeyWord("real",REAL),
new KeyWord("write", WRITE),
new KeyWord("while", WHILE)
};
//输出词法分析的结果以及错误信息
public Analyser(string input)
{
//初始化输入流,Token序列记录表,错误纪录表
reader = new StringReader(input);
tokenList = new Queue<Tokenizer>();
errorList = new ErrorList();
try
{
//读入第一行,使用按行读入式操作
lineBuf = reader.ReadLine();
}
catch (IOException e)
{
Console.WriteLine(e.StackTrace.ToString());
}
//行尾标示符处理
lineBuf += '\n';
//初始化行号
lineNum = 1;
//初始化列号
linePos = 0;
}
// 判断是否是数字或者字母
private bool isLetterOrDigit(int charInt)
{
if (isLetter(charInt) | isDigit(charInt))
return true;
return false;
}
// 判断是否是数字
private bool isDigit(int charInt)
{
char ch = (char)charInt;
if ('0' <= ch && ch <= '9')
return true;
return false;
}
// 判断是否是字母
private bool isLetter(int charInt)
{
char ch = (char)charInt;
if (('A' <= ch && ch <= 'Z') | ('a' <= ch && ch <= 'z'))
return true;
return false;
}
// 扫描函数,形成一个token
protected Tokenizer scan()
{
cToken = new Tokenizer();
cChar = "";
//开始处理下一个单词
processStartState();
//设置Token单词信息
cToken.setSymbol(cChar);
//判别单词是否为保留字
if (cToken.getCmm() == ID)
cToken.setCmm(reservedCheck(cToken.getSymbol()));
//设置Token序列行号
cToken.setLineNum(lineNum);
return cToken;
}
//读取下一个单词
protected int getNextChar()
{
//判断是否为文件尾
if (lineBuf == null)
return END;
//判断是否为行尾
if (linePos >= lineBuf.Length)
{
try
{
lineBuf = reader.ReadLine();
if (lineBuf == null)
return END;
else
{
lineBuf += '\n';
//初始化列号
linePos = 0;
lineNum++;
}
}
catch (IOException e)
{
Console.WriteLine(e.StackTrace);
}
}
return lineBuf[linePos++];
}
//回退一个字符,非常重要的一步
protected void unGetNextChar()
{
linePos--;
}
//处理开始状态,根据读入的第一个字符决定下一个要处理的状态(dfa)
private void processStartState()
{
int c = getNextChar();
if (isDigit(c))
{
unGetNextChar();
if (!isLetterOrDigit(getNextChar()) && getNextChar() != '.')
{
cChar += (char)c;
cToken.setCmm(NUM);
}
//处理并识别数字
else
{
processNumState();
}
}
else if (isLetter(c))
{
cChar += (char)c;
//处理ID
processIDState();
}
else if (c == '=')
{
if (getNextChar() != '=')
{
cChar += (char)c;
cToken.setCmm(EQ);
unGetNextChar();
}
else
{
cChar += (char)c;
processAssignState();
}
}
else if (c == '/')
{
if (getNextChar() != '*')
{
cToken.setCmm(OVER);
cChar += (char)c;
unGetNextChar();
}
else
{
c = getNextChar();
cChar += (char)c;
cToken.setCmm(LCOMMENT);
unGetNextChar();
}
}
else if (c == '*')
{
if (getNextChar() != '/')
{
cToken.setCmm(TIMES);
cChar += (char)c;
unGetNextChar();
}
else
{
c = getNextChar();
cChar += (char)c;
cToken.setCmm(RCOMMENT);
unGetNextChar();
}
}
else if (c == '\'')
{
cChar += (char)c;
//处理并识别单个字符
processCharState();
}
else if (c == ' ' || c == '\t' || c == '\n')
{
//完成状态,处理下一个单词
processStartState();
}
else
{
//处理并识别单字符分界符
switch (c)
{
case END:
cToken.setCmm(ENDFILE);
cChar += (char)c;
break;
case '<':
cToken.setCmm(LT);
cChar += (char)c;
break;
case '>':
cToken.setCmm(GT);
cChar += (char)c;
break;
case '+':
cToken.setCmm(PLUS);
cChar += (char)c;
break;
case '-':
cToken.setCmm(MINUS);
cChar += (char)c;
break;
case '(':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -