利用Python实现词法分析器(实验报告)

实验一 词法分析器的设计

一、实验目的

理解并掌握词法分析的原理与方法,能够使用某种语言实现词法分析程序。

二、实验要求

选用某种语言(如 C/C++)实现词法分析程序。词法分析程序的主要任务如下:

1. 识别出输入的源程序中的单词,输出二元组形式的单词序列。

2. 删除无用的空白字符、回车符等没有实质意义的字符。

3. 删除注释。

三、实验步骤

1. 选定进行词法分析的高级程序设计语言,给出该语言的文法。

<程序>::=<分程序>.

<分程序> ::=[<常量说明>][<变量说明>][<过程说明>]<语句>

<常量说明> ::=<常量定义>;

<常量定义> ::=<标识符>=<无符号整数>

<无符号整数> ::= <数字>{<数字>}

<变量说明> ::=<变量定义> <标识符>;

<变量定义> ::=char | string

<标识符> ::=<字母>{<字母>|<数字>}

<语句> ::=<赋值语句>|<条件语句>|<当循环语句>|<过程调用语句>

 |<复合语句>|<读语句><写语句>|<空>

<赋值语句> ::=<标识符>:=<表达式>

<表达式> ::= [+|-]<项>{<加法运算符> <项>}

<项> ::= <因子>{<乘法运算符> <因子>}

<因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’

<加法运算符> ::= +|-

<乘法运算符> ::= *|/

<关系运算符> ::= =|<>|<|<=|>|>=

<条件语句> ::=if <条件> else <语句>

<当循环语句> ::= WHILE <条件> : <语句>

<字母> ::= a|b|…|X|Y|Z

<数字> ::= 0|1|…|8|9

2. 设计单词种别表。

1 基本字 :bool,char ,char[,class,double,false,float,getchar,include,int,long,main,null,open,printf, private,public,put,read,return,short,scanf,signed,static,stdio,string,struct,true, unsigned,void

2 标识符:Letter

3 常数:number

4 运算符 :*,-,/,=,>,<,>=,==,<=,%,+,+=,-=,*=,/=

5 界符:

'(',')',',',';','.','{','}','<','>','"'
__author__ = 'PythonStriker'


Operation=['*','-','/','=','>','<','>=','==','<=','%','+','+=','-=','*=','/=']                                                      #词法分析器中分别运算符
Delimiter=['(',')',',',';','.','{','}','<','>','"']                                                                                 #词法分析器中分别界符
KeyWord=['bool','char' ,'char[','class','double','false','float','getchar','include','int','long','main','null','open','printf',
          'private','public','put','read','return','short','scanf','signed','static','stdio','string','struct','true',
          'unsigned','void']
LeftNoteFlag=0                                                                                                                      #/*注释清除标记
RightNoteFlag=0                                                                                                                     #*/注释清除标记

class Complier():                                                                                                                   #封装成编译器
    def IsLetter(self,Char):
         if((Char>='a' and Char<='z') or( Char>='A' and Char<='Z')):
                return True
         else:
                return False

    def IsDigit(self,Char):
         if(Char<='9' and Char>='0'):
             return True
         else:
             return False

    def IsSpace(self,Char):
         if(Char==' '):
             return True
         else:
             return False
    def RemoveSpace(self,List):                                                                                                       #清除字符串中前后的空格
        indexInList=0
        for String in List:
            List[indexInList]=String.strip()
            indexInList+=1
        return List

    def IsNote(self,String):                                                                                                        #判断注释类型
        global LeftNoteFlag
        global RightNoteFlag
        index=0
        for Char in String:
            if(index')
               elif(String in Delimiter):
                    if(String=='<' ):
                        if(List[indexInList] in KeyWord):
                            print('< <,分界符>')
                    elif(String=='>'):
                        if(List[indexInList-3] in Delimiter or List[indexInList-4] in KeyWord):
                            print('< >,分界符>')
                    else:
                        print('<'+String+',分界符>')
               elif(String in Operation):
                    if(String=='%'):
                        if(not(List[indexInList].isdigit())):
                            print('< %,格式符>')
                            FormatFlag=1
                            continue
                    print('<'+String+',运算符>')
               else:
                    if(String.isdigit()):
                        print('<'+String+',数字>')
                    elif(String.isalnum()):
                        if(FormatFlag==0):
                            print('<'+String+',变量>')
                        else:
                            print('<'+String+',格式变量>')
                            FormatFlag=0
            else:
                if(String in KeyWord):
                    print('<'+String+',关键字>')
                elif(String in Operation):
                    print('<'+String+',运算符>')
                else:
                    if(String.isdigit()):
                        print('<'+String+',数字>')
                    elif(String.isalnum()):
                        if(FormatFlag==0):
                            print('<'+String+',变量>')
                        else:
                            print('<'+String+',格式变量>')
                            FormatFlag=0


def main():
    ComPlier=Complier()
    SourceProgram=[]
    Filepath=input("请输入文件路径:")
    for line in open(Filepath,'r',encoding='UTF-8-sig' ):
        line=line.replace('\n','')
        SourceProgram.append(line)
    SourceProgram=ComPlier.DeleteNote(SourceProgram)
    SourceProgram=ComPlier.RemoveSpace(SourceProgram)
    SourceProgram=ComPlier.Reader(SourceProgram)
    ComPlier.JugeMent(SourceProgram)

if __name__ == "__main__":
    main()

测试代码文件代码:test.txt内编写C语言

#include
int main(){
int a = 0;            //author:pythonstriker
int b = 1;
printf("%d",a+b);


/*  just for test
return ;
}
*/

return 0;
}

测试结果:

利用Python实现词法分析器(实验报告)_第1张图片

结果成功删除注释, 同时删除没有用的空格回车,识别出输入的源程序中的单词,输出二元组形式的单词序列,为以后的语法分析器打下基础。

 如若输出版本不舒适还可换成如下版本:

__author__='PythonStriker'

KeySimple=['*','-','/','=','>','<','>=','==','<=','%','+','+=','-=','*=','/=']                                                                      #词法分析器中分别运算符
KeyAmbit=['(',')',',',';','.','{','}','<','>','"']                                                                                                                                #词法分析器中分别界符
KeyWord=[ 'bool','char' ,'char[','class','double','false','float','getchar','include','int','long','main','null','open','printf',
          'private','public','put','read','return','short','scanf','signed','static','stdio','string','struct','true',
          'unsigned','void']
WithoutSpaceKeyWord=['main','printf','scanf','open','read','true','false','getchar','put']

LeftNoteFlag=0                                                                                                                      #/*注释清除标记
RightNoteFlag=0                                                                                                                   #*/注释清除标记

class Assembly():                                                                                                                 #封装成编译器
    def IsLetter(self,Char):
         if((Char<='z' and Char>='a') or( Char<='Z' and Char>='A')):
                return True
         else:
                return False

    def IsNote(self,String):                                                                                                  #判断注释类型
        global LeftNoteFlag
        global RightNoteFlag
        NumberInString=0
        for Char in String:
            if(NumberInString='0'):
             return True
         else:
             return False

    def IsSpace(self,Char):
         if(Char==' '):
             return True
         else:
             return False

    def PassSpace(self,List):                                                                                                       #清除字符串中前后的空格
        NumberinList=0
        for String in List:
            List[NumberinList]=String.strip()
            NumberinList+=1
        return List
    
    
    def SplitSourceProgram(self,List):                                                                                  #字符串分割
        ListSplit = List.split("\\n")
        '''
        LIST = []
        for InIt in ListSplit:
            LIST.extend(InIt.split(";"))
        return LIST
        '''
        return ListSplit
    
   
    def DeleteNote(self,List):                                                                                                  #删除列表中的注释『'//'或者'/*   */'』
        RemoveList=[]
        FirstLeftNoteNumber=0
        NumberinList=0
        LeftNoteNumber=0
        global LeftNoteFlag
        global RightNoteFlag
        for String in List: 
            Flag=self.IsNote(String)
            NumberInString=0
            FirstLeftNoteNumber=0
            if(Flag):
                for Char in String:
                    if(NumberInString宏定义符号')
               elif(String in KeyAmbit):
                    if(String=='<' ):
                        if(List[NumberinList] in KeyWord):
                            print('<  ---------->分界符')
                    elif(String=='>'):
                        if(List[NumberinList-3] in KeyAmbit or List[NumberinList-4] in KeyWord):
                            print('>  ---------->分界符')
                    else:
                        print(String+'  ---------->分界符')
               elif(String in KeySimple):
                    if(String=='%'):
                        if(not(List[NumberinList].isdigit())):
                            print('%  ---------->格式符')
                            FormatFlag=1
                            continue
                    print(String+'  ---------->运算符')
               else:
                    if(String.isdigit()):
                        print(String+'  ---------->数字')
                    elif(String.isalnum()):
                        if(FormatFlag==0):
                            print(String+'  ---------->变量')
                        else:
                            print(String+'  ---------->格式变量')
                            FormatFlag==0
            else:
                if(String in KeyWord):
                    print(String+'  ---------->关键字')
                elif(String in KeySimple):
                    print(String+'  ---------->运算符')
                else:
                    if(String.isdigit()):
                        print(String+'  ---------->数字')
                    elif(String.isalnum()):
                        if(FormatFlag==0):
                            print(String+'  ---------->变量')
                        else:
                            print(String+'  ---------->格式变量')
                            FormatFlag==0


def main():
    AsseMbly=Assembly()
    SourceProgram=[]
    Filepath=input("请输入文件路径:")
    for line in open(Filepath,'r',encoding='UTF-8-sig' ):
        line=line.replace('\n','')
        SourceProgram.append(line)
    print(SourceProgram)
    SourceProgram=AsseMbly.DeleteNote(SourceProgram)
    print(SourceProgram)
    SourceProgram=AsseMbly.PassSpace(SourceProgram)
    SourceProgram=AsseMbly.Reader(SourceProgram)
    print(SourceProgram)
    AsseMbly.JugeMent(SourceProgram)

if __name__ == "__main__":
    main()

 输出结果如下:

利用Python实现词法分析器(实验报告)_第2张图片

 

你可能感兴趣的:(利用Python实现词法分析器(实验报告))