这编译原理的课设真烦呀,不过总算写完了。下面的我和室友写的代码(其实还有Bug,但过老师的检验还是够了),供大家去学习。主要去学习这个思想——嵌套与递归。
代码C++部分是我Liu Yudi写的,Python是室友Qu Ao和Che Pengyuan写的。
下面是PL/0语言的描述:
PL/0语言的BNF描述(扩充的巴克斯范式表示法)
<prog> → program <id>;<block>
<block> → [<condecl>][<vardecl>][<proc>]<body>
<condecl> → const <const>{
,<const>};
<const> → <id>:=<integer>
<vardecl> → var <id>{
,<id>};
<proc> → procedure <id>([<id>{
,<id>]});<block>{
;<proc>}
<body> → begin <statement>{
;<statement>}end
<statement> → <id> := <exp>
|if <lexp> then <statement>[else <statement>]
|while <lexp> do <statement>
|call <id>([<exp>{
,<exp>}])
|<body>
|read (<id>{
,<id>})
|write (<exp>{
,<exp>})
<lexp> → <exp> <lop> <exp>|odd <exp>
<exp> → [+|-]<term>{
<aop><term>}
<term> → <factor>{
<mop><factor>}
<factor>→<id>|<integer>|(<exp>)
<lop> → =|<>|<|<=|>|>=
<aop> → +|-
<mop> → *|/
<id> → l{
l|d} (注:l表示字母)
<integer> → d{
d}
注释:
<prog>:程序 ;<block>:块、程序体 ;<condecl>:常量说明 ;<const>:常量;
<vardecl>:变量说明 ;<proc>:分程序 ; <body>:复合语句 ;<statement>:语句;
<exp>:表达式 ;<lexp>:条件 ;<term>:项 ; <factor>:因子 ;<aop>:加法运算符;
<mop>:乘法运算符; <lop>:关系运算符
odd:判断表达式的奇偶性。
先来词法分析:
1.使用循环分支方法实现PL/0语言的词法分析器,该词法分析器能够读入使用PL/0语言书写的源程序,输出单词符号串及其属性到一中间文件中,具有一定的错误处理能力,给出词法错误提示(需要输出错误所在的行列)。
直接上代码:
C++
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
string a_line;
string reserve[36]={
"program","function","procedure","array","const",\
"file","label","of","packed","record","set","type",\
"var","case","do","downto","else","for","forward",\
"goto","if","repeat","then","to","until","while",\
"with","and","div","in","mod","not","or","begin",\
"end","nil"};
bool isreserve(string s);
int main(void)
{
fstream infile,outfile;
infile.open("source.txt",ios::in);
outfile.open("answer.txt",ios::out);
if(outfile.fail()||infile.fail())
{
cout<<"error"<<endl;
exit(0);
}
int row = 1; //row代表行数
while(getline(infile,a_line,'\n')) //每次读取一行
{
int column=0; //column代表这一行的第几列个字符
string temp;
while(column<a_line.size())
{
if(isalpha(a_line[column]))
{
int i=1;
temp+=a_line[column];
while(isalpha(a_line[column+1])||isdigit(a_line[column+1]))
{
temp+=a_line[column+1];
column++;
i++;
}
if(isreserve(temp))
{
//cout<<temp<<endl;
outfile<<"<"<<temp<<" , reserve"<<">"<<endl;
}
else
outfile<<"<"<<temp<<" , symbol"<<">"<<endl;
temp.erase();
}
else if(isdigit(a_line[column]))
{
int i=1;
temp+=a_line[column];
bool flag=0;
while(isalpha(a_line[column+1])||isdigit(a_line[column+1]))
{
temp+=a_line[column+1];
if(isalpha(temp[i]))
flag=1;
column++;
i++;
}
if(flag==0)
outfile<<"<"<<temp<<" , number"<<">"<<endl;
else //说明出现数字打头的保留字
cout<<"row: "<<row<<" column: "<<column<<" is error!"<<endl;
temp.erase();
}
else if(a_line[column]=='+'||a_line[column]=='-'||a_line[column]=='*'||a_line[column]=='/'||a_line[column]=='=')
outfile<<"<"<<a_line[column]<<" , operator"<<">"<<endl;
else if((a_line[column]=='/'&&a_line[column+1]=='*')||(a_line[column]=='*'&&a_line[column+1]=='/'))
outfile<<"<"<<a_line[column]<<a_line[column+1]<<" , bound symbol"<<">"<<endl;
else if(a_line[column]==';'||a_line[column]=='('||a_line[column]==')'||a_line[column]==',')
outfile<<"<"<<a_line[column]<<" , bound symbol"<<">"<<endl;
else if(a_line[column]==':')
{
if(a_line[column+1]=='=')
{
outfile<<"<"<<a_line[column]<<a_line[column+1]<<" , operator"<<">"<<endl;
column++;
}
else
cout<<"row: "<<row<<" column: "<<column<<" is error!"<<endl;
}
else if(a_line[column]=='<')
{
if(a_line[column+1]=='='||a_line[column+1]=='>')
{
outfile<<"<"<<a_line[column]<<a_line[column+1]<<" , operator"<<">"<<endl;
column++;
}
else
outfile<<"<"<<a_line[column]<<" , operator"<<">"<<endl;
}
else if(a_line[column]=='>')
{
if(a_line[column+1]=='=')
{
outfile<<"<"<<a_line[column]<<a_line[column+1]<<" , operator"<<">"<<endl;
column++;
}
else
outfile<<"<"<<a_line[column]<<" , operator"<<">"<<endl;
}
column++;
}
row++;
}
outfile.close();
infile.close();
return 0;
}
bool isreserve(string s)
{
for(int i = 0;i<36;i++)
if(s.compare(reserve[i]) == 0)
{
return true;
}
return false;
}
Python
# -*- coding: utf-8 -*-
"""
Created on Sun Sep 27 18:19:51 2020
@author: chepengyuan
"""
#定义保留字
RESERVED_WORD= ['write','read','program','function','procedure','array','const','file','label','of','packed','record','set','type','var','case','do','downto','else','for','forward','goto','if','repeat','then','to','until','call','while','with','and','div','in','mod','not','or','begin','end','nil']
#判断保留字,如果是保留字则返回保留字,否则返回False
def Is_Key(key):
if key in RESERVED_WORD:
return key
else:
return False
def List_to_Str(l):
l = str(l)
#删除无用的字符,[ ] '
l = l.replace("'",'')
l = l.replace("[",'')
l = l.replace("]",'')
l = l.replace(",",'')
l = l.replace(' ','')
return l
CL = []#符号表
#读入源程序
fp = open('3.txt','r',encoding = 'utf-8')
#缓冲区
buffer = fp.read()
print('缓冲区buffer:',buffer)
#替换换行符
buffer = buffer.strip()
#行指针
line = 1
c = []
#获取一个字符
i = 0#字符指针
while i <len(buffer):
#跳过空格和换行符
while(buffer[i]==' '):
print('空格',buffer[i])
i = i + 1
'''
while(True):
if buffer[i] =='\n':
i = i + 1
line = line + 1
print(line)
else:
break
'''
#读入单词首字符
c.append(buffer[i])
#如果是字母,则继续读取字符串,判断是保留字还是普通符号
if c[-1].isalpha():
#读入一个字符
i = i+1
if i<=len(buffer)-1:
c.append(buffer[i])
while(c[-1].isalpha() or c[-1].isdigit()):
#判断是否为字符或数字,如果是,则继续读入
if i<len(buffer) -1:
i = i + 1
c.append(buffer[i])
else:
break
#如果不是,则退回一个字符
if i <len(buffer)-1:
i = i -1
print('退回:',c[-1])
del (c[-1])
#将当前已经读入的字符列表转换为字符串
c = List_to_Str(c)
#判断获取的字符是否为保留字,如果是,则返回保留字
if (Is_Key(c)):
print('保留字:',c)
token = {
'value':List_to_Str(c),'attribute':'reserved_word','line_num':line}
CL.append(token)
c=list(c)
c.clear()
#如果不是,则插入符号表,返回标志符类型及在符号表中的指针
else:
print('变量',c)
token = {
'value':List_to_Str(c),'attribute':'identifier','line_num':line}
CL.append(token)
#Insert_Character_Table(c)
#清空当前字符串
c=list(c)
c.clear()
#如果是数字则继续读入直到读完所有数字
elif(c[-1].isdigit()):
i = i + 1
c.append(buffer[i])
while(c[-1].isdigit()):
i = i + 1
c.append(buffer[i])
#退回一个字符
i = i -1
del(c[-1])
#插入常数表,返回整型数据类型及在常数表中的指针
#Insert_Const_Table(c)
c = List_to_Str(c)
print('整型数据类型','常数表中的指针',c)
token = {
'value':List_to_Str(c),'attribute':'number','line_num':line}
CL.append(token)
c=list(c)
c.clear()
#如果是运算符,则返回
elif c[-1] =='(':
print('符号:',c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del(c[-1])
elif c[-1] ==')':
print('符号:',c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del(c[-1])
elif c[-1] ==';':
print('符号:',c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del(c[-1])
elif c[-1] =='=':
print('符号:',c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del(c[-1])
elif c[-1] ==',':
print('符号:',c[-1])
token = {
'value':c[-1],'attribute':'界符','line_num':line}
CL.append(token)
del(c[-1])
elif c[-1] =='+':
print('符号:',c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del(c[-1])
elif c[-1] =='/':
print('符号:',c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del(c[-1])
elif c[-1] ==':':
#读入一个字符
i = i + 1
c.append(buffer[i])
#判断是否为=,如果是则返回:=
if(c[-1] == '='):
print('符号:',c[-2],c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del (c[-2],c[-1])
#如果不是,则退回一个字符,返回*
else:
i = i-1
del (c[-1])
print('符号:',c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del(c[-1])
elif c[-1] =='*':
#读入一个字符
i = i + 1
c.append(buffer[i])
#判断是否为*,如果是则返回**
if(c[-1] == '*'):
print('符号:',c[-2],c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del c[-1],c[-2]
#如果不是,则退回一个字符,返回*
else:
i = i-1
del (c[-1])
print('符号:',c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del(c[-1])
elif c[-1] =='<':
#读入一个字符
i = i + 1
c.append(buffer[i])
#判断是否为>,如果是则返回<>
if(c[-1]=='>'):
print('符号:',c[-2],c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del c[-2],c[-1]
#判断是否为=,如果是则返回<=
elif(c[-1] == '='):
print('符号:',c[-2],c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del(c[-2],c[-1])
#如果不是>,=,则退回一个字符,返回<
else:
i = i -1
del(c[-1])
print('符号:',c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del(c[-1])
elif c[-1] =='>':
#读入一个字符
i = i + 1
c.append(buffer[i])
#判断是否为=,如果是则返回>=
if(c[-1] =='='):
print('符号:',c[-2],c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del (c[-2],c[-1])
#如果不是,则退回一个字符,返回>
else:
i = i-1
del(c[-1])
print('符号:',c[-1])
token = {
'value':List_to_Str(c),'attribute':'界符','line_num':line}
CL.append(token)
del(c[-1])
elif c[-1]==' ':
print(c[-1],'识别到空格')
del c[-1]
#如果时换行符,则跳过并行数加一
elif c[-1]=='\n':
print('识别到换行符',c[-1])
line = line + 1
del(c[-1])
#如果啥都不是,则报错,并清空
else:
print(c)
print('出错字符:',c[-1])
print(c)
del(c[-1])
print('_____________ERROR________________'+line)
#下个单词的首字符
i =i + 1
fp = open('rr.txt','w')
fp.write(str(CL))
print(CL)
下面是语法分析:
根据上机练习一给出的PL/0语言扩充的巴克斯范式语法描述,利用递归下降的语法分析方法,编写PL/0语言的语法分析程序。
要求:
- 对给出的PL/0语言进行分析,证明其可以进行自上而下的语法分析;
- 对block、proc、statement、condition、expression、term、factor进行分析,画出语法分析图,在此基础上描述这些子程序的设计思想;
- 具有一定的语法错误处理能力;
上代码
C++
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#include <iomanip>
using namespace std;
int n=0;
string a_line;
int num = 0; // 结构体数组下标
struct yufa
{
string SYM; // 单词的类别
string strToken; // 用户所定义的标识符的值
int line; // 记录换行符的个数,即记录源文件的行数
}temp,yufa[1000];
string reserve[15]={
"begin", "end", "if", "then", "else", "while", "write", "read", "do", "call", "const", "var", "procedure", "program", "odd"};
bool isreserve(string s);
void prog();
void block();
void _const_();
void body();
void statement();
void exp();
void term();
void factor();
void lexp();
int main(void)
{
fstream infile;
infile.open("source1.txt",ios::in);
if(infile.fail())
{
cout<<"error"<<endl;
exit(0);
}
int row = 1; //row代表行数
while(getline(infile,a_line,'\n')) //每次读取一行
{
int column=0; //column代表这一行的第几列个字符
string temp;
while(column<a_line.size())
{
if(isalpha(a_line[column]))
{
int i=1;
temp+=a_line[column];
while(isalpha(a_line[column+1])||isdigit(a_line[column+1]))
{
temp+=a_line[column+1];
column++;
i++;
}
if(isreserve(temp))
{
yufa[n].SYM = temp;
yufa[n].strToken = temp;
yufa[n].line = row;
n++;
cout<<"<"<<temp<<" , reserve"<<">"<<endl;
}
else
{
yufa[n].SYM = "biaoshifu";
yufa[n].strToken = temp;
yufa[n].line = row;
n++;
cout<<"<"<<temp<<" , symbol"<<">"<<endl;
}
temp.erase();
}
else if(isdigit(a_line[column]))
{
int i=1;
temp+=a_line[column];
bool flag=0;
while(isalpha(a_line[column+1])||isdigit(a_line[column+1]))
{
temp+=a_line[column+1];
if(isalpha(temp[i]))
flag=1;
column++;
i++;
}
if(flag==0)
{
yufa[n].SYM = "digit";
yufa[n].strToken = temp;
yufa[n].line = row;
n++;
cout<<"<"<<temp<<" , number"<<">"<<endl;
}
else //说明出现数字打头的保留字
cout<<"row: "<<row<<" column: "<<column<<" is error!"<<endl;
temp.erase();
}
else if(a_line[column]=='+'||a_line[column]=='-'||a_line[column]=='*'||a_line[column]=='/'||a_line[column]=='=')
{
temp+=a_line[column];
yufa[n].SYM = temp;
yufa[n].strToken = temp;
yufa[n].line = row;
n++;
cout<<"<"<<a_line[column]<<" , operator"<<">"<<endl;
temp.erase();
}
/* else if((a_line[column]=='/'&&a_line[column+1]=='*')||(a_line[column]=='*'&&a_line[column+1]=='/'))
cout<<"<"<<a_line[column]<<a_line[column+1]<<" , bound symbol"<<">"<<endl;*/
else if(a_line[column]==';'||a_line[column]=='('||a_line[column]==')'||a_line[column]==',')
{
temp+=a_line[column];
yufa[n].SYM = temp;
yufa[n].strToken = temp;
yufa[n].line = row;
n++;
cout<<"<"<<a_line[column]<<" , bound symbol"<<">"<<endl;
temp.erase();
}
else if(a_line[column]==':')
{
if(a_line[column+1]=='=')
{
yufa[n].SYM = "fuzhi";
yufa[n].strToken = ":=";
yufa[n].line = row;
n++;
cout<<"<"<<a_line[column]<<a_line[column+1]<<" , operator"<<">"<<endl;
column++;
}
else
cout<<"row: "<<row<<" column: "<<column<<" is error!"<<endl;
temp.erase();
}
else if(a_line[column]=='<')
{
if(a_line[column+1]=='=')
{
yufa[n].SYM = "le";
yufa[n].strToken = "<=";
yufa[n].line = row;
n++;
cout<<"<"<<a_line[column]<<a_line[column+1]<<" , operator"<<">"<<endl;
column++;
}
else if(a_line[column+1]=='>')
{
yufa[n].SYM = "ne";
yufa[n].strToken = "<>";
yufa[n].line = row;
n++;
cout<<"<"<<a_line[column]<<a_line[column+1]<<" , operator"<<">"<<endl;
column++;
}
else
{
yufa[n].SYM = "l";
yufa[n].strToken = "<";
yufa[n].line = row;
n++;
cout<<"<"<<a_line[column]<<" , operator"<<">"<<endl;
}
temp.erase();
}
else if(a_line[column]=='>')
{
if(a_line[column+1]=='=')
{
yufa[n].SYM = "ge";
yufa[n].strToken = ">=";
yufa[n].line = row;
n++;
cout<<"<"<<a_line[column]<<a_line[column+1]<<" , operator"<<">"<<endl;
column++;
}
else
{
yufa[n].SYM = "g";
yufa[n].strToken = ">";
yufa[n].line = row;
n++;
cout<<"<"<<a_line[column]<<" , operator"<<">"<<endl;
}
temp.erase();
}
column++;
}
row++;
}
infile.close();
for(int i=0;i<n;i++)
{
cout<<yufa[i].line<<"\t"<<yufa[i].SYM<<"\t"<<yufa[i].strToken<<endl;
}
prog();
for(int i = 0;i<n-1;i++)
{
if(yufa[i].SYM == ")"&&yufa[i+1].SYM !=";")
cout<<"line"<<yufa[i].line<<": 分号缺失"<<endl;
if(yufa[i].SYM == "("&&yufa[i+1].SYM == ")")
cout<<"line"<<yufa[i].line<<": 函数内变量缺失"<<endl;
}
system("pause");
return 0;
}
bool isreserve(string s)
{
for(int i = 0;i<15;i++)
{
if(s.compare(reserve[i]) == 0)
return true;
}
return false;
}
/*<prog> → program <id>;<block>*/
void prog()
{
temp = yufa[num];
cout<<"进入 prog 模块"<<endl;
if(temp.SYM!="program")
{
num++;
temp = yufa[num];
if(temp.SYM!=";")
{
cout<<"line"<<temp.line<<": program 拼写错误"<<endl;
}
else
{
num--;
cout<<"line"<<temp.line<<": program 缺失"<<endl;
}
}
else
{
num++;
}
temp = yufa[num];
if(temp.SYM != "biaoshifu")
{
cout<<"line"<<temp.line<<": 标识符错误"<<endl;
}
else
{
num++;
}
temp = yufa[num];
if(temp.SYM!=";")
{
cout<<"line"<<temp.line-1<<": 分号缺失"<<endl;
}
else
{
num++;
}
cout<<"prog 模块结束"<<endl;
block();
}
/*
<block> → [<condecl>][<vardecl>][<proc>]<body>
<condecl> → const <const>{,<const>};
<vardecl> → var <id>{,<id>};
<proc> → procedure <id>([<id>{,<id>]});<block>{;<proc>}
*/
void block()
{
cout<<"进入 block 模块"<<endl;
temp = yufa[num];
if(temp.SYM == "const")
{
num++;
_const_();
temp = yufa[num];
while(temp.SYM == ",")
{
num++;
_const_();
temp = yufa[num];
}
if(temp.SYM == ";")
{
num++;
temp = yufa[num];
}
else
{
temp = yufa[num-1];
cout<<"line"<<temp.line<<": 分号缺失"<<endl;
}
temp = yufa[num];
cout<<"const 模块结束"<<endl;
}
if(temp.SYM == "var")
{
cout<<"进入 var 模块"<<endl;
num++;
temp = yufa[num];
if(temp.SYM == "biaoshifu")
{
num++;
temp = yufa[num];
}
else
{
cout<<"line"<<temp.line<<": 缺少变量声明"<<endl;
}
while(temp.SYM == ",")
{
num++;
temp = yufa[num];
if(temp.SYM == "biaoshifu")
{
num++;
temp = yufa[num];
}
else
{
cout<<"line"<<temp.line<<": 逗号后变量缺失"<<endl;
}
}
if(temp.SYM == ";")
{
num++;
temp = yufa[num];
}
else
{
temp = yufa[num-1];
cout<<"line"<<temp.line<<": 分号缺失"<<endl;
num++;
}
cout<<"var 模块结束"<<endl;
}
while(temp.SYM == "procedure")
{
cout<<"进入 procedure 模块"<<endl;
num++;
temp = yufa[num];
if(temp.SYM == "biaoshifu")
{
num++;
temp = yufa[num];
if(temp.SYM == "(")
{
num++;
temp = yufa[num];
if(temp.SYM == "biaoshifu")
{
num++;
temp = yufa[num];
}
while(temp.SYM == ",")
{
num++;
temp = yufa[num];
if(temp.SYM == "biaoshifu")
{
num++;
temp = yufa[num];
}
}
if(temp.SYM == ")")
{
num++;
}
else
{
cout<<"line"<<temp.line<<": 右括号缺失"<<endl;
}
}
else
{
cout<<"line"<<temp.line<<": 左括号缺失"<<endl;
}
}
else
{
cout<<"line"<<temp.line<<": 函数名错误"<<endl;
}
temp = yufa[num];
if(temp.SYM != ";")
{
cout<<"line"<<temp.line<<": 分号缺失"<<endl;
}
else
{
num++;
}
block();
temp = yufa[num];
if(temp.SYM == ";")
{
num++;
temp = yufa[num];
}
else
{
break;
}
}
body();
cout<<"block 模块结束"<<endl;
}
/*<body> → begin <statement>{;<statement>}end*/
void body()
{
cout<<"进入 body 模块"<<endl;
int k=0;
temp = yufa[num];
//cout<<temp.SYM;
/*if(temp.SYM!="begin")
{
num++;
cout<<"line"<<temp.line<<" begin is missed"<<endl;
}
else
{
num++;
}*/
if(temp.SYM == "begin")
{
for(int i = num;i<n;i++)
if(yufa[i].SYM == "end")
k++;
if(k == 0)
cout<<"line"<<temp.line<<": begin 的 end 缺失"<<endl;
}
/*else if(temp.SYM != "begin")
{
cout<<"line"<<temp.line<<"begin缺失"<<endl;
}*/
num++;
statement();
temp = yufa[num];
while(temp.SYM == ";")
{
num++;
temp = yufa[num];
if(temp.SYM == "end")
{
break;
}
else
{
statement();
temp = yufa[num];
}
}
if(temp.SYM != "end")
{
//cout<<"line"<<temp.line<<" end is missed"<<endl;
}
else
num++;
cout<<"body 模块结束"<<endl;
}
/*
<statement> → <id> := <exp>
|if <lexp> then <statement>[else <statement>]
|while <lexp> do <statement>
|call <id>([<exp>{,<exp>}])
|<body>
|read (<id>{,<id>})
|write (<exp>{,<exp>})
*/
void statement()
{
cout<<"进入 statement 模块"<<endl;
temp = yufa[num];
//cout<<temp.line<<temp.strToken<<endl;
if(temp.SYM == "biaoshifu")
{
num++;
temp = yufa[num];
//cout<<temp.SYM<<endl;
if(temp.SYM != "fuzhi")
{
//cout<<"line"<<temp.line<<": 赋值符缺失"<<endl;
}
else
num++;
exp();
}
else if(temp.SYM == "if")
{
cout<<"进入 if 模块"<<endl;
num++;
lexp();
temp = yufa[num];
if(temp.SYM != "then")
{
cout<<"line"<<temp.line<<": then缺失"<<endl;
}
else
num++;
statement();
temp = yufa[num];
if(temp.SYM == "else")
{
statement();
temp = yufa[num];
if(temp.SYM!=";")
cout<<"line"<<temp.line<<": 分号缺失"<<endl;
else
num++;
}
}
else if(temp.SYM == "while")
{
cout<<"进入 while 模块"<<endl;
num++;
lexp();
temp = yufa[num];
if(temp.SYM != "do")
{
cout<<"line"<<temp.line<<": do缺失"<<endl;
}
else
{
num++;
statement();
}
cout<<"while 结束"<<endl;
}
else if(temp.SYM == "call")
{
cout<<"进入 call 模块"<<endl;
num++;
temp = yufa[num];
if(temp.SYM != "biaoshifu")
{
cout<<"line"<<temp.line<<": 函数名错误"<<endl;
}
else
{
num++;
temp = yufa[num];
if(temp.SYM != "(")
cout<<"line"<<temp.line<<": 右括号缺失"<<endl;
else
num++;
exp();
temp = yufa[num];
while(temp.SYM == ",")
{
num++;
temp = yufa[num];
exp();
temp = yufa[num];
}
if(temp.SYM != ")")
{
cout<<"line"<<temp.line<<": 左括号缺失"<<endl;
}
else
num++;
}
}
else if(temp.SYM == "read")
{
cout<<"进入 read 模块"<<endl;
num++;
temp = yufa[num];
if(temp.SYM != "(")
cout<<"line"<<temp.line<<": 左括号缺失"<<endl;
else
num++;
temp = yufa[num];
if(temp.SYM != "biaoshifu")
cout<<"line"<<temp.line<<": 变量缺失"<<endl;
else
num++;
temp = yufa[num];
while(temp.SYM == ",")
{
num++;
temp = yufa[num];
if(temp.SYM == "biaoshifu")
{
num++;
temp = yufa[num];
}
else
cout<<"line"<<temp.line<<": 逗号后变量缺失"<<endl;
}
if(temp.SYM != ")")
cout<<"line"<<temp.line<<": 右括号缺失"<<endl;
else
num++;
}
else if(temp.SYM == "write")
{
cout<<"进入 write 模块"<<endl;
num++;
temp = yufa[num];
//cout<<temp.SYM<<endl<<endl<<endl;
if(temp.SYM != "(")
{
cout<<"line"<<temp.line<<": 左括号缺失"<<endl;
}
else
num++;
exp();
temp = yufa[num];
while(temp.SYM == ",")
{
num++;
exp();
temp = yufa[num];
}
if(temp.SYM != ")")
cout<<"line"<<temp.line<<": 右括号缺失"<<endl;
else
num++;
cout<<"write 模块结束"<<endl;
}
else
cout<<"statement 模块结束"<<endl;
}
/*<exp> → [+|-]<term>{<aop><term>}*/
void exp()
{
cout<<"进入 exp 模块"<<endl;
temp = yufa[num];
if(temp.SYM == "+"|| temp.SYM == "-")
{
num++;
term();
}
else
term();
temp = yufa[num];
while(temp.SYM == "+"|| temp.SYM == "-")
{
num++;
term();
temp = yufa[num];
}
cout<<"exp 模块结束"<<endl;
}
/*<term> → <factor>{<mop><factor>}*/
void term()
{
cout<<"进入 term 模块"<<endl;
factor();
temp = yufa[num];
while(temp.SYM == "*"|| temp.SYM == "/")
{
num++;
factor();
temp = yufa[num];
}
cout<<"term 模块结束"<<endl;
}
/*<factor>→<id>|<integer>|(<exp>)*/
void factor()
{
cout<<"进入 factor 模块"<<endl;
temp = yufa[num];
if(temp.SYM == "biaoshifu")
num++;
else if(temp.SYM == "digit")
num++;
else if(temp.SYM == "(")
{
num++;
exp();
temp = yufa[num];
if(temp.SYM != ")")
cout<<"line"<<temp.line<<": 右括号缺失"<<endl;
}
cout<<"factor 模块结束"<<endl;
}
/*<lexp> → <exp> <lop> <exp>|odd <exp>*/
void lexp()
{
cout<<"进入 lexp 模块"<<endl;
temp = yufa[num];
if(temp.SYM == "odd")
{
exp();
}
else
{
exp();
temp = yufa[num];
if(temp.SYM!="="&&temp.SYM!="ne"&&temp.SYM!="l"&&temp.SYM!="le"&&temp.SYM!="g"&&temp.SYM!="ge")
cout<<"line"<<temp.line<<": 比较运算符缺失"<<endl;
else
num++;
exp();
cout<<"lexp 模块结束"<<endl;
}
}
/*<const> → <id>:=<integer>*/
void _const_()
{
cout<<"进入 const 模块"<<endl;
temp = yufa[num];
if(temp.SYM == "biaoshifu")
{
num++;
temp = yufa[num];
if(temp.SYM == "fuzhi")
{
num++;
temp = yufa[num];
if(temp.SYM == "digit")
{
num++;
}
else
{
temp = yufa[num-1];
cout<<"line"<<temp.line<<": 赋值符号后不是数字"<<endl;
}
}
else
{
cout<<"line"<<temp.line<<": 赋值符缺失"<<endl;
}
}
else
{
cout<<"line"<<temp.line<<": 标识符错误"<<endl;
}
cout<<"const 模块结束"<<endl;
}
Python
室友一
#语法分析的任务:
#根据文法产生式,判断给定的输入符号串是否为一个句子
index = 0
ERROR= [] #错误信息列表
def get_token():
global index
if index < len(CL):
return CL[index]
else:
print('分析完成')
# <prog> → program <id>;<block>
def prog():
global index
token = get_token()
print('进入prog分析')
if token['value'] != 'program': # 第一个单词不是program,两种错误,拼写或缺失错误
index = index + 1
token = get_token()
if token['value'] != ';':
#拼写错误
print('出错行数:',token['line_num'], '\t\t错误原因:program拼写错误')
else:
#缺失错误
index = index - 1
print('出错行数:',token['line_num'], '\t\t错误原因:缺少program关键字')
else:
index = index + 1
token = get_token()
if token['attribute'] != 'identifier': # 第二个是程序名称
print('出错行数:',token['line_num'], '\t\t出错原因:语法错误,缺少程序名称')
else:
index = index + 1
token = get_token()
if token['value'] != ';': # 第三个是分号 然后进入block阶段
print('出错行数:',token['line_num'], '\t\t出错原因:缺少;')
else:
index = index + 1
print('prog___________________over')
block()
# <block> → [<condecl>][<vardecl>][<proc>]<body>
# 考虑到因为;缺失导致获取的下一个单词不方便放回去,所以condecl vardecl proc在block层进行解析
def block():
# 常量表达式 <condecl> → const <const>{,<const>};
print('进入block分析')
global index
token = get_token()
if token['value'] == 'const':
index = index + 1
const()
token = get_token()
while token['value'] == ',':
index = index + 1
const()
token = get_token()
if token['value'] == ';':
index = index + 1
token = get_token()
else:
print('出错行数:',token['line_num'], '\t\t错误原因:缺少 ;')
# 变量表达式 <vardecl> → var <id>{,<id>};
if token['value'] == 'var':
print('进入变量分析')
index = index + 1
token = get_token()
if token['attribute'] == 'identifier':
index = index + 1
token = get_token()
else:
print('出错行数:',token['line_num'], '\t\t错误原因:var后缺少变量声明')
while token['value'] == ',':
index = index + 1
token = get_token()
if token['attribute'] == 'identifier':
index = index + 1
token = get_token()
if token['value'] == ';':
index = index + 1
token = get_token()
else:
print('出错行数:',token['line_num'], '\t\t错误原因:缺少 ;')
print('变量分析完成')
# 这里用while循环表示函数定义可以嵌套
# 函数定义 <proc> → procedure <id>([<id>{,<id>}]);<block>{;<proc>}
while token['value'] == 'procedure':
print('进入函数分析(---------------procedure)')
index = index + 1
token = get_token()
if token['attribute'] != 'identifier':
print('出错行数:',token['line_num'], '\t\t出错原因:函数名必须是标识符')
else:
index = index + 1
token = get_token()
if token['value'] != '(':
print('出错行数:',token['line_num'], '\t\t出错原因 :缺少(')
else:
index = index + 1
token = get_token()
if token['attribute'] != 'identifier':
print('出错行数:',token['line_num'], '\t\t出错原因 :缺少函数参数')
else:
index = index + 1
token = get_token()
#[<id>{,<id>}]
while token['value'] == ',':
index = index + 1
token = get_token()
if token['attribute'] == 'identifier':
index = index + 1
token = get_token()
if token['value'] != ')':
print('出错行数:',token['line_num'], '\t\t出错原因 :缺少 )')
else:
index = index + 1
token = get_token()
if token['value'] != ';':
#当产生错误时,index不再前进,报错后继续向后分析
print('出错行数:',token['line_num'], '\t\t出错原因:缺少;')
else:
index = index + 1
# 下面进入block定义 进入block之前需要更新嵌套层数level 同时记录当前栈的情况便于恢复
block()
token = get_token()
if token['value'] == ';': # 如果是分号 继续进行proc
index = index + 1
token = get_token()
elif token['value'] != 'procedure':
break
elif token['value'] == 'procedure':
print('出错行数:',token['line_num'], '\t\t出错原因:缺少;')
#<body>
body()
print('block分析完成')
# <const> → <id>:=<integer>
def const():
print('进入常量分析')
global index
token = get_token()
if token['attribute'] != 'identifier': # 这里有变量 需要记录在符号表中
print(token['line_num'], '缺少标识符')
else:
index = index + 1
token = get_token()
if token['value'] != ':=':
print('出错行数:',token['line_num'], '\t\t出错原因:缺少:=')
else:
index = index + 1
token = get_token()
if token['attribute'] != 'number':
print('出错行数:',token['line_num'], '\t\t出错原因::=后面需要跟整数')
else:
index = index + 1
print('常量分析完成')
# <body> → begin <statement>{;<statement>}end
def body():
print('进入body分析')
global index
token = get_token()
if token['value'] != 'begin':
index = index + 1
print('出错行数:',token['line_num'], '\t\t出错原因:缺少begin')
else:
index = index + 1
statement()
token = get_token()
#??????????????????????处理缺失的;????????????????????????
while token['value']==';' or is_statement()==True: # 循环statement
if token['value']!=';':
prior = index - 1
if CL[prior]['value']!='end':
print('出错行数:',token['line_num'], '\t\t出错原因:缺少 ;')
else:
index = index + 1
statement()
token = get_token()
print(token['value'])
print('55555555555555555555555555555555555555555555555')
token = get_token()
if token['value'] != ';':
print('出错行数:',token['line_num'], '\t\t出错原因:缺少;')
else:
index = index + 1
token =get_token()
if token['value'] != 'end':
print('出错行数:',token['line_num'], '\t\t出错原因:缺少end')
else:
print('识别到end')
index = index + 1
print('body分析完成')
# <statement> → <id> :=<exp>;
# |if <lexp> then <statement>[else <statement>]
# |while <lexp> do <statement>
# |call <id>([<exp>{,<exp>}])
# |<body>
# |read (<id>{,<id>})
# |write (<exp>{,<exp>})
def is_statement():
token = get_token()
if token['value'] in ['if','while','call','read','write','begin']:
return True
elif token['attribute'] == 'identifier':
return True
else:
return False
def statement():
global index
'''
if token['value'] == 'end': # 这一步是因为如果最后有人多写了一个; 会继续进入statement,但实际上会退出
error(token['line_num'], ';是多余的')
token_index -= 1
return
'''
# <id> := <exp>
print('进入statement分析')
token = get_token()
print('statement识别到',token['value'])
#print(token['value'],'44444444444444444444444444')
if token['attribute'] == 'identifier':
index = index + 1
token = get_token()
if token['value'] != ':=':
print('出错行数:',token['line_num'],'\t\t出错原因:缺少:=')
else:
#print(token['value'],'5555555555555555555555555555555555555')
index = index + 1
#print(token['value'],'66666666666666666666666666')
expression()
# if <lexp> then <statement>[else <statement>]
elif token['value'] == 'if':
print('进入if语句分析')
index = index + 1
lexp()
token = get_token()
# print('____________________当前token',token)
if token['value'] != 'then':
print('出错行数:',token['line_num'], '\t\t出错原因:缺少关键字then')
else:
print('_____________识别到then___________')
index = index + 1
statement()
token = get_token()
print('dangqian',token['value'])
if token['value'] == 'else':
statement()
token = get_token()
if token['value']!=';':
print('出错行数:',token['line_num'],'\t\t出错原因:缺少 ; ')
else:
index = index + 1
# while <lexp> do <statement>
elif token['value'] == 'while':
print('进入while语句分析')
index = index + 1
lexp()
token = get_token()
if token['value'] != 'do':
print('出错行数:',token['line_num'], '\t\t出错原因:缺少do关键字')
else:
index = index + 1
statement()
print('while语句分析完成')
# call <id>([<exp>{,<exp>}])
elif token['value'] == 'call':
print('进入call==========================')
index = index + 1
token = get_token()
if token['attribute'] != 'identifier':
print('出错行数:',token['line_num'], '\t\t出错原因:函数名必须是标识符')
else:
print('识别到',token['value'])
index = index + 1
token = get_token()
if token['value']!='(':
print('出错行数:',token['line_num'],'\t\t出错原因:缺少(')
else:
print('识别到',token['value'])
index = index + 1
#?????????????????????????????????????
token = get_token()
print('识别到===========+++++++++',token['value'])
if token['value']==')':
print('识别到-----------',token['value'])
else:
expression()
while token['value']==',':
print(token['value'],11111111111111111111111111111)
index = index + 1
expression()
token = get_token()
token = get_token()
if token['value'] != ')':
print(token['value'],'errrrrrrrrrrrrrrrrrrrrrrrrrrr')
print('出错行数:',token['line_num'],'\t\t出错原因:缺少 )')
else:
index = index + 1
#read (<id>{,<id>})
elif token['value'] == 'read':
print('进入read语句分析')
index = index + 1
token = get_token()
if token['value'] != '(':
print('出错行数:',token['line_num'],'\t\t出错原因:缺少(')
else:
print('识别到 _________(____________')
index = index +1
token = get_token()
if token['attribute'] !='identifier':
print('出错行数:',token['line_num'],'\t\t出错原因:缺少变量')
else:
print('识别到',token['value'])
index = index + 1
token = get_token()
while(token['value'] == ','):
index = index + 1
token = get_token()
if token['attribute'] != 'identifier':
print('出错行数:',token['line_num'],'\t\t出错原因:,后缺少变量')
else:
print('识别到',token['value'])
if index !=len(CL)-1:
index = index + 1
token = get_token()
if token['value'] !=')':
print('出错行数:',token['line_num'],'\t\t出错原因:缺少 )')
else:
print('识别到',token['value'])
index = index + 1
print('read分析完成')
# write (<exp>{,<exp>})
elif token['value'] == 'write':
print('进入write语句分析-------------------------------------')
index = index + 1
token = get_token()
if token['value'] !='(':
print('出错行数:',token['line_num'],'\t\t出错原因:write后缺少(')
else:
index = index + 1
expression()
token = get_token()
while token['value'] == ',':
index = index + 1
expression()
token = get_token()
if token['value'] !=')':
print('出错行数:',token['line_num'],'\t\t出错原因:缺少)')
else:
index = index + 1
print('write语句分析完成')
# body
elif token['value']=='begin':
print('----------------------------------再次进入body分析-----------------------------------------------')
body()
print('statement分析完成')
# <exp> → [+|-]<term>{<aop><term>}
def expression():
print('进入expression分析')
global index
token = get_token()
#print(token['value'],'44444444444444444444444444')
if token['value'] == '+' or token['value'] == '-':
index = index + 1
term()
else:
term()
token = get_token()
while token['value'] == '+' or token['value'] == '-':
print('识别到',token['value'])
index = index + 1
term()
token = get_token()
print('expression分析完成')
# <term> → <factor>{<mop><factor>}
def term():
print('进入term分析')
global index
factor()
token = get_token() # 处理乘除
while token['value'] == '*' or token['value'] == '/':
index = index + 1
factor()
token = get_token()
print('term分析完成')
# <factor>→<id>|<integer>|(<exp>)
def factor():
print('进入factor分析')
global index
token = get_token()
if token['attribute'] == 'identifier':
print('识别到变量',token['value'])
index = index + 1
elif token['attribute'] == 'number': # 遇到数字
print('识别到',token['value'])
index = index + 1
elif token['attribute'] == '(': # 遇到左括号要进入表达式
index = index + 1
expression()
token = get_token()
if token['attribute'] != ')': # 没有右括号报错
print('出错行数:',token['line_num'], '\t\t出错原因:缺少 )')
else:
print('出错行数:',token['line_num'],'\t\t出错原因:此处缺少factor')
print('factor分析完成')
#??????????????????????????????????????????????????????
# <lexp> → <exp> <lop> <exp>|odd <exp>
# <lop> → =|<>|<|<=|>|>=
def lexp():
print('进入lexp分析')
global index
token = get_token()
if token['value'] == 'odd':
expression()
else:
expression()
token = get_token()
# <lop> → =|<>|<|<=|>|>=
if token['value'] != '=' and token['value'] != '<>' and token['value'] != '<' and token['value'] != '<=' \
and token['value'] != '>' and token['value'] != '>=':
print('出错行数:',token['line_num'], '\t\t出错原因:缺少比较运算符')
else:
print('识别到比较运算符',token['value'])
index = index + 1
expression()
print('lexp分析完成')
try:
prog()
except:
if index ==len(CL):
if CL[index-1]['value'] !='end':
print('出错行数:',index-1, '\t\t出错原因:缺少end')
print('__________________________________分析完成_____________________________')
else:
print('unkown error index = ',index)
'''
<block> → [<condecl>][<vardecl>][<proc>]<body>
<condecl> → const <const>{,<const>};
<const> → <id>:=<integer>
<vardecl> → var <id>{,<id>};
<proc> → procedure <id>([<id>{,<id>]});<block>{;<proc>}
<body> → begin <statement>{;<statement>}end
<statement> → <id> := <exp>
|if <lexp> then <statement>[else <statement>]
|while <lexp> do <statement>
|call <id>([<exp>{,<exp>}])
|<body>
|read (<id>{,<id>})
|write (<exp>{,<exp>})
<lexp> → <exp> <lop> <exp>|odd <exp>
<exp> → [+|-]<term>{<aop><term>}
<term> → <factor>{<mop><factor>}
<factor>→<id>|<integer>|(<exp>)
<lop> → =|<>|<|<=|>|>=
<aop> → +|-
<mop> → *|/(**//)
<id> → l{l|d} (注:l表示字母)
<integer> → d{d}
注释:
<prog>:程序 ;<block>:块、程序体 ;<condecl>:常量说明 ;<const>:常量;
<vardecl>:变量说明 ;<proc>:分程序 ; <body>:复合语句 ;<statement>:语句;
<exp>:表达式 ;<lexp>:条件 ;<term>:项 ; <factor>:因子 ;<aop>:加法运算符;
<mop>:乘法运算符; <lop>:关系运算符
odd:判断表达式的奇偶性。
'''
室友二
def keep(a,k,i):
if a[k:i] in save:
return 1
else:
return 0
save=['write','read','call','program','function','procedure','array','const','file','label','of','packed','record','set','type','var','case','do','downto','else','for','forward','goto','if','repeat','then','to','until','while','with','and','div','in','mod','not','or','begin','end','nil','readln']
get1=[]
with open('1.txt','r',encoding='utf-8') as f:
a=f.read()
i=0
while i<len(a):
b=a
if b[i]==' ' or b[i]=='\n':
pass
else:
k=i
#print(b[k])
if b[i].isalpha():
c=b
while c[i].isalpha() or c[i].isdigit():
i=i+1
if i==len(c):
break;
#print(i)
if keep(b,k,i):
get1.append("保留字:"+b[k:i])
i=i-1
else:
get1.append("变量:"+b[k:i])
i=i-1
else:
if b[i].isdigit():
while b[i].isdigit():
i=i+1
if i==len(c):
break;
get1.append("常量:"+b[k:i])
i=i-1
else:
if b[i]==':':
if b[i+1]=='=':
i=i+1
get1.append("符号:"+b[k:i+1])
else:
get1.append("符号:"+b[k:i+1])
elif b[i]=='>':
if b[i+1]=='=':
i=i+1
get1.append("符号:"+b[k:i+1])
else:
get1.append("符号:"+b[k:i+1])
elif b[i]=='<':
if b[i+1]=='=':
i=i+1
get1.append("符号:"+b[k:i+1])
else:
get1.append("符号:"+b[k:i+1])
elif b[i]=='<':
if b[i+1]=='>':
i=i+1
get1.append("符号:"+b[k:i+1])
else:
get1.append("符号:"+b[k:i+1])
else:
get1.append("符号:"+b[k:i+1])
i=i+1
print(get1)
def printii(get1):
i=0
while i<len(get1):
if get1[i]!="符号::=":
print(get1[i].split(':')[1],end=' ')
else:
print(":=",end=' ')
i=i+1
print('\n')
def p1(get1):
if p21(get1):
return False
if p22(get1):
return False
if p23(get1):
return False
if block(get1):
return False
return True
def p21(get1):
#print(get1[0].split(':')[1])
if get1[0].split(':')[1]=='program':
get1.pop(0)
return False
else:
return True
def p22(get1):
if get1[0].split(':')[0]=='变量':
get1.pop(0)
return False
else:
return True
def p23(get1):
if get1[0].split(':')[1]==';':
get1.pop(0)
return False
else:
return True
def block(get1):#匹配成功返回False
if get1[-1]!='保留字:end':
return True
i=len(get1)-2
j=1
while i>=0 and j!=0:
if get1[i]=='保留字:begin':
j=j-1
elif get1[i]=='保留字:end':
j=j+1
i=i-1
if i==-1 and j!=0:
return True
i=i+1
get2=get1[0:i]
get3=get1[i:len(get1)]
#print(get2)
#print(get3)
if convar(get2) and body(get3):
return False
return True
def convar(get2):#匹配成功返回True
while len(get2)>0:
get2i=[]
while len(get2)>0:
if get2[0]!='符号:;':
get2i.append(get2[0])
get2.pop(0)
else:
get2.pop(0)
break
printii(get2i)
#print(proc(get2i))
if proc(get2i):
#print(block(get2))
return not block(get2)
get2=[]
if condec(get2i) or vardec(get2i):#匹配成功返回真
continue
else:
return False
return True
def condec(get2i):
get2j=[]
j=0
while j<len(get2i):
get2j.append(get2i[j])
j=j+1
if get2j[0]=='保留字:const':
get2j.pop(0)
else:
return False ###
i=0
while i<len(get2j):
if i%4==0 and get2j[i].split(':')[0]=="变量":
i=i+1
continue
if i%4==1 and get2j[i]=="符号::=":
i=i+1
continue
if i%4==2 and get2j[i].split(':')[0]=="常量":
i=i+1
continue
if i%4==3 and get2j[i].split(':')[1]==",":
i=i+1
continue
return False
return True
def vardec(get2i):
get2j=[]
j=0
while j<len(get2i):
get2j.append(get2i[j])
j=j+1
if get2j[0]=='保留字:var':
get2j.pop(0)
else:
return False
i=0
while i<len(get2j):
if i%2==0 and get2j[i].split(':')[0]=="变量":
i=i+1
continue
if i%2==1 and get2j[i].split(':')[1]==",":
i=i+1
continue
return False
return True
def proc(get2i):
get2j=[]
j=0
while j<len(get2i):
get2j.append(get2i[j])
j=j+1
if len(get2j)>3 and get2j[0]=='保留字:procedure' and get2j[1].split(':')[0]=="变量" and get2j[2]=='符号:(':
get2j.pop(0)
get2j.pop(0)
get2j.pop(0)
else:
return False
#print(get2j)
i=0
while i<len(get2j) and get2j[i]!='符号:)':
if i%2==0 and get2j[i].split(':')[0]=="变量":
i=i+1
continue
if i%2==1 and get2j[i]=="符号:,":
i=i+1
continue
return False
#print(get2j[i])
if get2j[i]=='符号:)':
return True
else:
return False
'''
get2j=get2j[i+1:len(get2i)]
j=0
while get2j[j]!="保留字:procedure"&j<len(get2j):
j=j+1
if get2j[j-1]!="符号:;":
get2m=get2j[0:j-1]
get2n=get2j[j:len(get2j)]
block(get2m)
proc(get2n)
else:
return False
'''
def body(get3):#匹配成功返回True
if get3[0]=='保留字:begin' and get1[-1]=='保留字:end':
get3.pop(0)
get3.pop(-1)
else:
return False
while len(get3)>0:
get3i=[]
while len(get3)>0:
if get3[0]!='符号:;':
get3i.append(get3[0])
get3.pop(0)
else:
get3.pop(0)
break
printii(get3i)
if statement(get3i):
continue
else:
return False
return True
def statement(get3i):
if stat1(get3i) or stat2(get3i) or stat3(get3i) or stat4(get3i) or stat5(get3i) or stat6(get3i) or stat7(get3i):#匹配成功返回真
return True
else:
return False
def stat1(get2i):
get3i=[]
j=0
while j<len(get2i):
get3i.append(get2i[j])
j=j+1
if get3i[0].split(':')[0]=="变量" and get3i[1]=="符号::=":
get3i.pop(0)
get3i.pop(0)
else:
return False
#time.sleep(4)
return exp(get3i)
def stat2(get2i):
get3i=[]
j=0
while j<len(get2i):
get3i.append(get2i[j])
j=j+1
if get3i[0]=="保留字:if":
get3i.pop(0)
else:
return False
j=0
while j<len(get3i) and get3i[j]!="保留字:then":
j=j+1
if j==len(get3i):
return False
else:
get3j=get3i[0:j]
get3k=get3i[j:len(get3i)]
if lexp(get3j):
pass
else:
return False
get3k.pop(0)
j=0
while j<len(get3k) and get3k[j]!="保留字:else":
j=j+1
if j==len(get3k):
return statement(get3k)
else:
get3m=get3k[0:j]
get3n=get3k[j+1:len(get3k)]
#print(get3m)
#print(statement(get3m))
if statement(get3m) and statement(get3n):
return True
else:
return False
def stat3(get2i):
get3i=[]
j=0
while j<len(get2i):
get3i.append(get2i[j])
j=j+1
if get3i[0]=="保留字:while":
get3i.pop(0)
else:
return False
j=0
while j<len(get3i) and get3i[j]!="保留字:do":
j=j+1
if j==len(get3i):
return False
else:
get3m=get3i[0:j]
get3n=get3i[j+1:len(get3i)]
#print(get3n)
#print(statement(get3n))
if lexp(get3m) and statement(get3n):
return True
else:
return False
def stat4(get2i):
get3i=[]
j=0
while j<len(get2i):
get3i.append(get2i[j])
j=j+1
if len(get3i)>=3 and get3i[0]=="保留字:call" and get3i[1].split(':')[0]=="变量" and get3i[2]=="符号:(" and get3i[len(get3i)-1]=="符号:)":
get3i.pop(0)
get3i.pop(0)
get3i.pop(0)
get3i.pop(len(get3i)-1)
else:
return False
#print(get3i)
while len(get3i)>0:
get3j=[]
while len(get3i)>0:
if get3i[0]!='符号:,':
get3j.append(get3i[0])
get3i.pop(0)
else:
get3i.pop(0)
break
if exp(get3j):
continue
else:
return False
return True
def stat5(get2i):
get3i=[]
j=0
while j<len(get2i):
get3i.append(get2i[j])
j=j+1
return body(get3i)
def stat6(get2i):
get3i=[]
j=0
while j<len(get2i):
get3i.append(get2i[j])
j=j+1
if len(get3i)>3 and get3i[0]=="保留字:read" and get3i[1]=="符号:(" and get3i[len(get3i)-1]=="符号:)":
get3i.pop(0)
get3i.pop(0)
get3i.pop(len(get3i)-1)
else:
return False
while len(get3i)>0:
get3j=[]
while len(get3i)>0:
if get3i[0]!='符号:,':
get3j.append(get3i[0])
get3i.pop(0)
else:
get3i.pop(0)
break
if len(get3j)==1 and get3j[0].split(':')[0]=="变量":
continue
else:
return False
return True
def stat7(get2i):
get3i=[]
j=0
while j<len(get2i):
get3i.append(get2i[j])
j=j+1
if get3i[0]=="保留字:write" and get3i[1]=="符号:(" and get3i[len(get3i)-1]=="符号:)":
get3i.pop(0)
get3i.pop(0)
get3i.pop(len(get3i)-1)
else:
return False
if len(get3i)==0:
return False
while len(get3i)>0:
get3j=[]
while len(get3i)>0:
if get3i[0]!='符号:,':
get3j.append(get3i[0])
get3i.pop(0)
else:
get3i.pop(0)
break
if exp(get3j):
continue
else:
return False
return True
def lexp(get1):
#print(get1)
get2i=[]
j=0
while j<len(get1):
get2i.append(get1[j])
j=j+1
if get2i[0]=='odd':
get1.pop(0)
return exp(get2i)
else:
get3i=[]
j=0
while j<len(get2i):
get3i.append(get2i[j])
j=j+1
while len(get3i)>0:
get3j=[]
while len(get3i)>0:
if lop(get3i[0]):
get3i.pop(0)
break
else:
get3j.append(get3i[0])
get3i.pop(0)
if exp(get3j):
continue
else:
return False
return True
def exp(get2i):
get3i=[]
j=0
while j<len(get2i):
get3i.append(get2i[j])
j=j+1
while len(get3i)>0:
get3j=[]
while len(get3i)>0:
if get3i[0]!='符号:+' and get3i[0]!='符号:-':
get3j.append(get3i[0])
get3i.pop(0)
else:
get3i.pop(0)
break
if len(get3j)>0 and term(get3j):
continue
else:
return False
return True
def term(get2i):
get3i=[]
j=0
while j<len(get2i):
get3i.append(get2i[j])
j=j+1
while len(get3i)>0:
get3j=[]
while len(get3i)>0:
if get3i[0]!='符号:*' and get3i[0]!='符号:/':
get3j.append(get3i[0])
get3i.pop(0)
else:
get3i.pop(0)
break
if len(get3j)>0 and factor(get3j):
continue
else:
return False
return True
def factor(get1):
if len(get1)==1 and (get1[0].split(':')[0]=="变量" or get1[0].split(':')[0]=="常量"):
return True
else:
return False
def lop(get1):
if get1=='符号:>' or get1=='符号:<' or get1=='符号:<>' or get1=='符号:<=' or get1=='符号:>=' or get1=='符号:=':
return True
else:
return False
print(p1(get1))
C++测试文件(source.txt)错误自己添加
program xi;
const a:=5;
var j,sum,x;
procedure sum1(x);
begin
while j<=5 do
write (x);
if j <=1 then
read (x);
write (x);
call sum1(j+1);
write(x);
end
Python测试文件1(3.txt)错误自己添加
program xi;
const a:=5;
var j,sum,x;
procedure sum1(x);
begin
j:=1;
sum:=0;
while j<=x do
write(sum);
read(x);
write(x);
begin
read(j);
write(j);
write(x);
end
read(j);
write(j);
call sum1(j+5);
write(j);
end
Python测试文件2(1.txt)错误自己添加
program xi;
const a:=5;
var j,sum,x;
procedure sum1(x);
begin
if a>b1
then
while j<=x
write (sum)
else
call sum1(j + 5)
end
begin
j:=1;
sum:=0;
read(x);
write(x);
read(j);
write(j);
call s (j+5);
write(j)
end
以上代码可跑通,但可能有Bug,我觉得明年NUAA的学弟学妹可能用得到哈哈哈!加油!