📄 plxcompile.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace PlxCompiler
{
class PlxCompile
{
//一些数组的上界
const int MAX_LINECHAR = 1024;
const int MAX_NUMBERSIZE = 14;
const int MAX_ANSICNUMBER = 128;
const int MAX_INDENTFIERLEN = 36;
const int MAX_INDENTNUMBER = 1024;
const int MAX_CODENUMBER = 2048;
const int MAX_STACKLIMIT = 2048;
const int MAX_KEYWORD = 32;
const int MAX_ERROR = 100;
//
const int plus = 0; // +
const int minus = 1; // -
const int times = 2; // *
const int slash = 3; // /
const int remainder = 42; // %
const int cifang = 43; // x^y ^
const int lparen = 4; // (
const int rparen = 5; // )
const int eql = 6; // =
const int comma = 7; // ,
const int semicolon = 8; // ;
const int period = 9; // .
const int lss = 10; // <
const int gtr = 11; // >
const int ident = 12; //
const int number = 14; //
const int becomes = 15; // :=
const int geq = 16; // >=
const int leq = 17; // <=
const int neql = 18; // /=
const int nul = 19; //
const int progsym = 20;
const int intesym = 21;
const int logisym = 22;
const int constsym = 23;
const int ifsym = 24;
const int thensym = 25;
const int elsesym = 26;
const int whilesym = 27;
const int repeasym = 28;
const int beginsym = 29;
const int endsym = 30;
const int orsym = 31;
const int andsym = 32;
const int xorsym = 42;
const int notsym = 33;
const int truesym = 34;
const int falsesym = 35;
const int dosym = 36;
const int untilsym = 37;
const int writesym = 38;
const int procsym = 39;
const int callsym = 40;
const int term = 41; /* 结束 */
const int commentsym = 100;
public Form1 form1;
//构造函数
public PlxCompile(Form1 parent)
{
cc = ll = 0;
tx = 0; /* 用0专门来做查询 */
cx = 0;
dx = 0;
lev = 0;
errornum = 0;
lineIndex = 1;
//各种数组的实例化
id = "";
word = new string[MAX_KEYWORD];
line = ""; //当前行字符
wsym = new int[MAX_KEYWORD]; //关键字索引
a = ""; //标识符缓存
ssym = new int[MAX_ANSICNUMBER]; //运算符索引
s = new int[MAX_STACKLIMIT]; //运行栈
code = new CODE[MAX_CODENUMBER]; //存储代码的数组
table = new TABLE[MAX_INDENTNUMBER];
errorMax = MAX_ERROR;
form1 = parent;
word[0] = "program";
word[1] = "integer";
word[2] = "logical";
word[3] = "const";
word[4] = "if";
word[5] = "then";
word[6] = "else";
word[7] = "while";
word[8] = "repeat";
word[9] = "begin";
word[10] = "end";
word[11] = "or";
word[12] = "and";
word[13] = "not";
word[14] = "true";
word[15] = "false";
word[16] = "do";
word[17] = "until";
word[18] = "write";
word[19] = "procedure";
word[20] = "call";
word[21] = "xor";
wsym[0] = progsym;
wsym[1] = intesym;
wsym[2] = logisym;
wsym[3] = constsym;
wsym[4] = ifsym;
wsym[5] = thensym;
wsym[6] = elsesym;
wsym[7] = whilesym;
wsym[8] = repeasym;
wsym[9] = beginsym;
wsym[10] = endsym;
wsym[11] = orsym;
wsym[12] = andsym;
wsym[13] = notsym;
wsym[14] = truesym;
wsym[15] = falsesym;
wsym[16] = dosym;
wsym[17] = untilsym;
wsym[18] = writesym;
wsym[19] = procsym;
wsym[20] = callsym;
wsym[21] = xorsym;
for (int i = 0; i < 128; i++)
ssym[i] = -1;
ssym['+'] = plus;
ssym['-'] = minus;
ssym['*'] = times;
ssym['/'] = slash;
ssym['%'] = remainder;
ssym['^'] = cifang;
ssym['('] = lparen;
ssym[')'] = rparen;
ssym['='] = eql;
ssym[','] = comma;
ssym[';'] = semicolon;
ssym['.'] = period;
ssym['<'] = lss;
ssym['>'] = gtr;
ssym['$'] = term;
}
// 文件操作
public void FileOpen(string filename)
{
try
{
FileIn = File.OpenText(filename);
}
catch (Exception e)
{
error(0);
}
}
public void FileOpen()
{
try
{
FileIn = File.OpenText(FilePath);
}
catch (IOException e)
{
error(0);
}
}
public bool FileClose()
{
try
{
FileIn.Close();
return true;
}
catch (IOException e)
{
error(-1);
return false;
}
}
private string FilePath;
private StreamReader FileIn;
private void error(string a)
{
errornum++;
if (errornum > errorMax) return;
form1.outerror("ERROR"+errornum+" 行号: "+(lineIndex-1)+":列号: "+ll+" "+line+ch+ " "+ a+"\r\n");
}
private void error(string a, int b)
{
errornum++;
if (errornum > errorMax) return;
form1.outerror("ERROR" + errornum + " 行号-" + (lineIndex - 1) + ":列号-" + ll + " " + line + a + "\r\n");
}
private void error(int errorNo)
{
errornum++;
if (errornum > errorMax) return;
}
// 词法分析
int cc; //当前字符号
int ll; //当前行数目
string line; //当前行字符
char ch; //当前读取字符
int lineIndex; //当前行号
string[] word; //关键字串
int[] wsym; //关键字索引
string a; //标识符缓存
int[] ssym; //运算符索引
string id; //三种变量缓存
int sym;
int num;
void getch()
{
if (cc != ll)
{
ch = line[cc++];
return;
}
else
{
if (FileIn.EndOfStream)
{
ch = '$';
return;
}
}
cc = ll = 0;
lineIndex++;
//char[] temp = (FileIn.ReadLine()).ToCharArray();
line = FileIn.ReadLine() + " "; //temp;
ll = line.Length;
//line[ll++] = ' ';
ch = line[cc++];
}
void getsym()
{
while (ch == ' ' || ch == 9) getch();
/* 字符串识别 */
if (ch <= 'z' && ch >= 'a')
{
int i = 0;
a = "";
do
{
if (i < MAX_INDENTFIERLEN - 1)
{
//a.Insert(i++,ch+"");
a = a + ch;
i++;
}
else
{
break;
}
getch();
}
while ((ch <= 'z' && ch >= 'a') || (ch <= '9' && ch >= '0'));
id = String.Copy(a);
sym = ident;
for (i = 0; i < MAX_KEYWORD; i++)
{
if (id.Equals(word[i]))
{
sym = wsym[i]; break;
}
}
}
else
{
/* 数字识别 */
if (ch <= '9' && ch >= '0')
{
int i = 0;
num = 0;
do
{
i++;
num = 10 * num + ((int)ch - '0');
getch();
}
while (ch <= '9' && ch >= '0');
if (i > MAX_NUMBERSIZE)
{
error("数字的位数超出范围!");
}
sym = number;
}
else
{
/* 赋值号识别 */
if (ch == ':')
{
getch();
if (ch == '=')
{
getch();
sym = becomes;
}
else
{
error("赋值符号缺少 '=' 符号!");
}
}
else
{
/* 小于号识别 */
if (ch == '<')
{
getch();
if (ch == '=')
{
sym = leq;
getch();
}
else
{
sym = lss;
}
}
else
{
/* 大于号识别 */
if (ch == '>')
{
getch();
if (ch == '=')
{
getch();
sym = geq;
}
else
{
sym = gtr;
}
}
else
{
if (ch == '/')
{
getch();
/*注释处理 */
if (ch == '/')
{
getch();
cc = ll;
sym = commentsym;
getch();
getsym();
return;
}
else
{
/* C注释处理 */
if (ch == '*')
{
getch();
while (true)
{
while (ch != '*')
{
getch();
if (ch == '$')
{
sym = term;
error("缺少注释边界!");
return;
}
}
getch();
if (ch == '/')
{
getch();
sym = commentsym;
getsym();
break;
}
}
}
/* 不等于处理 */
else
{
if (ch == '=')
{
getch();
sym = neql;
}
else
{
sym = slash;
}
}
}
}
else
{
if (ch > 0 && ch < 129)
{
sym = ssym[ch];
if (sym == -1)
{
error("使用不合法标识符!");
}
getch();
}
else
{
error("未知名的字符! ");
getch();
}
}
}
}
}
}
}
}
//public static void Main()
//{
// PlxCompile plx = new PlxCompile();
// plx.FileOpen("D:\\C#\\procedure.plx");
// plx.Compiler();
// plx.showCode();
// plx.interpret();
// Console.WriteLine(plx.lineIndex);
//}
/* 语法分析 */
public enum vartype : int { varConst, varInteger, varLogical, varProc };
//typedef enum _kind _kind;
/* 变量,过程存储数据结构 */
public struct TABLE
{
public string name;
public vartype kind;
public int adr;
public int level;
public int size;
public int val;
};
TABLE[] table; // 存储区
int tx; // table表指针
int lev; // 静态层次计数
int dx; // 局部变量指针
public int errornum; // 语法错误数目
public int errorMax;
//enter
void enter(vartype indent) /* 变量入表函数 */
{
if (position(id) != 0)
{
error("重复定义!");
}
else
{
tx++;
table[tx].name = String.Copy(id);
table[tx].kind = indent;
switch (indent)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -