编译原理之C++&&Python进行Pascal的词法分析&&语法分析

这编译原理的课设真烦呀,不过总算写完了。下面的我和室友写的代码(其实还有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语言的语法分析程序。
要求:

  1. 对给出的PL/0语言进行分析,证明其可以进行自上而下的语法分析;
  2. 对block、proc、statement、condition、expression、term、factor进行分析,画出语法分析图,在此基础上描述这些子程序的设计思想;
  3. 具有一定的语法错误处理能力;
上代码

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的学弟学妹可能用得到哈哈哈!加油!

猜你喜欢

转载自blog.csdn.net/weixin_43916997/article/details/109190349