PL0语言词法分析程序

合集下载

编译原理实践5—PL0的词法分析程序构造

编译原理实践5—PL0的词法分析程序构造

辅助过程getch
getsym需要一个辅助过程getch,每被 调用一次就读入下一个字符 除此之外的任务:
识别行结束标志,作为空格符处理 拷贝原文输出 在输出文件每行开始添加坐标(书中例子程 序没有体现)
3.词法分析程序的设计
每调用一次getsym,首先用循环结构在 源程序上向前读入一个非空格字符,然 后对此字符进行分析,转相应部分处理 getsym大致可以分为三个部分
字符语法分析安排在同一遍中
,此时词法分析作为语法分析程序的一个子程序。每 当语法分析需要一个新的符号时,就调用词法分析子 程序,词法分析子程序从字符串源程序中识别出一个 具有独立意义的单词,将其符号返给语法分析。这种 方法避免了中间文件,省去了送取符号工作,有利于 提高编译程序的效率。书中采用这种方案。
取符号
字符串源程序
词法分析器
送符号
语法分析器
程序getsym
本课程采用第2种方案,程序名getsym,预先 审视源程序下一个符号,并将读入的符号放在 变量sym中,语法分析的判断分析将以这个读 入的符号为基础 具体任务:
跳过空格字符 识别像begin、end、if、while等这样的保留字 识别非保留字,作为标识符处理 识别数字 识别专用符号组合,如:=、<=、>= 识别特殊的单个字符,如+、-、/、* 跳过注释行(书中例子程序没有体现)
本课程采用第二种方法,Lex方法将在 后续时间补充介绍
2.词法分析程序的任务
词法分析程序的任务:对源程序进行扫描,提 供一个个符号给语法分析程序。 简称为扫描器(scanner)或扫描程序 词法分析程序实现的2种方案: 1.先单独工作一遍,把字符流源程序先变为符号 序列,输出到一个中间文件上,然后将这个文 件作为语法分析程序的输入继续第二遍的编译 过程

编写词法分析程序

编写词法分析程序

实验报告课程名称:编译原理__ 项目名称:编写词法分析程序姓名:专业:计算机科学与技术_ 班级:2011级学号:同组成员:1注:1、实验准备部分包括实验环境准备和实验所需知识点准备。

2、若是单人单组实验,同组成员填无。

二、实验过程记录2:1、实验目的给出PL/0文法规范,要求编写PL/0语言的词法分析程序,深刻理解词法分析的整个过程,提高词法分析方法的实践能力2、实验内容对PL/0语言作如下功能扩充:(1)扩充条件语句的功能使其为:if<条件>then <语句>[else <语句>](2)增加repeat语句,格式为:repeat<语句>{;<语句>}until<条件>3、实验要求要求:(1)给出扩充后的语法图和EBNF的语法描述。

(2)修改PL/0的编译系统,使它能正确编译扩充后的PL/0程序。

4、实验步骤:(1)整型一维数组,数组的定义格式为:VAR<数组标识名>(<下界>:<上界>)其中上界和下界可以是整数或者常量标识名。

访问数组元素的时候,数组下表是整型的表达式,包括整数、常量或者变量和他们的组合。

(2)扩充条件语句,格式为:<条件语句> ::= IF<条件>THEN<语句> [ELSE<语句>]扩充条件语句的语法图为:2注:实验过程记录要包含实验目的、实验原理、实验步骤,页码不够可自行添加。

(3)增加repeatT语句,格式为:<复合语句> ::= repeat<语句>UNTL<条件>扩充repeat语句的语法图为:源程序代码:#include<stdio.h>#include<string.h>inti,j,k,sign,number,flag,run,sum,autuor;charch;charwords[10]={""};charprogram[500];intScan(charprogram[]){char*keywords[39]={ "auto","default","do","extern","goto","int","short","static","struct","switch", "typedef","void","break","case","char","const","continue","double","else","enum ","float","for","if","long","register","return","signed","zhaixinyuan","sizeof" ,"union","unsigned","volatile","while","main","printf","scanf","include","defin e","string"};number=0;flag=0;j=0;ch=program[i++];while((ch=='')||(ch=='\r')||(ch=='\n'))ch=program[i++];if((ch>='a')&&(ch<='z')){while((ch>='a')&&(ch<='z')){words[j++]=ch;ch=program[i++];}i--;words[j++]='\0';for(k=0;k<38;k++)if(strcmp(words,keywords[k])==0)keywords[k])==0{sign=k+1;flag=1;if(k==27)autuor=1;break;}if(flag==0){sign=100;运行结果:3注:1、实验小结应包含实验所需知识点和实验方法的总结,实验心得体会等。

pl0语法分析词法分析语义分析

pl0语法分析词法分析语义分析

作者:love冥天出处:PL/O语言是Pascal语言的一个子集,我们这里分析的PL/O的编译程序包括了对PL/O语言源程序进行分析处理、编译生成类PCODE代码,并在虚拟机上解释运行生成的类PCODE代码的功能。

PL/O语言编译程序釆用以语法分析为核心、一遍扫描的编译方法。

词法分析和代码生成作为独立的子程序供语法分析程序调用。

语法分析的同时,提供了出错报告和出错恢复的功能。

在源程序没有错误编译通过的情况下,调用类PCODE解释程序解释执行生成的类PCODE代码。

词法分析子程序分析:词法分析子程序名为getsym,功能是从源程序中读出一个单词符号(token), 把它的信息放入全局变量sym. id和num中,语法分析器需要单词时,直接从这三个变量中获得。

(注意!语法分析器每次用完这三个变量的值就立即调用getsym子程序获取新的单词供下一次使用。

而不是在需要新单词时才调用getsym iS 程。

)getsym过程通过反复调用getch子过程从源程序过获取字符,并把它们拼成单词。

getch过程中使用了行缓冲区技术以提高程序运行效率。

词法分析器的分析过程:调用getsym时,它通过getch过程从源程序中获得一个字符。

如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查保留字表,如果查到为保留字,则把sym变量赋成相应的保留字类型值;如果没有查到,则这个单词应是一个用户自定义的标识符(可能是变量名、常量名或是过程的名字),把sym置为ident,把这个单词存入id变量。

查保留字表时使用了二分法查找以提高效率。

如果getch获得的字符是数字,则继续用getch获取数字,并把它们拼成一个整数,然后把sym置为number,并把拼成的数值放入num变量。

如果识别出其它合法的符号(比如:赋值号、大于号、小于等于号等),则把sym则成相应的类型。

如果遇到不合法的字符,把sym置成nul。

语法分析子程序分析:语法分析子程序采用了自顶向下的递归子程序法,语法分析同时也根据程序的语意生成相应的代码,并提供了出错处理的机制。

《编译原理(实验部分)》实验3_PL0语法分析

《编译原理(实验部分)》实验3_PL0语法分析

《编译原理(实验部分)》实验3_PL0语法分析《编译原理》(实验部分)实验3_PL0语法分析一、实验目的加深和巩固对于语法分析的了解和掌握;给出PL/0文法规范,要求编写PL/0语言的语法分析程序。

二、实验设备1、PC 兼容机一台;操作系统为WindowsWindowsXP。

2、Visual C++ 6.0 或以上版本, Windows 2000 或以上版本,汇编工具(在Software 子目录下)。

三、实验原理PL/O语言的编译程序,是用高级语言PASCAL语言书写的。

整个编译过程是由一些嵌套及并列的过程或函数完成。

语法分析是由过程BLOCK完成。

采用自顶向下的递归子程序法。

所产生的目标程序为假象栈式计算机的汇编语言。

对目标程序的执行是由PASCAL语言书写的解释程序进行的。

四、实验步骤实验代码int lp=0;int rp=0;#define getsymdo if(-1==getsym()) return -1#define expressiondo() if(-1==expression()) return -1#define termdo() if(-1==term()) return -1#define factordo() if(-1==factor()) return -1int expression();//语法分析int factor(){if(sym!=ident &&sym!=number&&sym!=lparen){err++;if(err==1) printf("语法错误: \n");printf("error----Factor Needs Ident or Number or Lparen\n");}if ((sym == ident) || (sym == number) || (sym == lparen)){if (sym == ident){WordAnalyse();if(getsym()==-1){return -1;}if(sym!=times&&sym!=slash&&sym!=plus&&sym!=minus &&sym!=rparen){err++;if(err==1) printf("语法错误: \n");printf("变量后没有跟上+-*\\ \n");}if(lp==0 && sym==rparen){err++;if(err==1) printf("语法错误: \n");printf("没有左括号匹配\n");}}else if (sym == number){WordAnalyse();if(getsym()==-1){return -1;}if(sym!=times&&sym!=slash&&sym!=plus&&sym!=minus &&sym!=rparen) {err++;if(err==1) printf("语法错误: \n");printf("数字后没有跟上+-*\\ \n");}if(lp==0 && sym==rparen){err++;if(err==1) printf("语法错误: \n");printf("没有左括号匹配\n");}}else if (sym == lparen){WordAnalyse();lp++;if(getsym()==-1){lp--;err++;if(err==1) printf("语法错误: \n");printf("error----Needs Rparen \n");return -1;}expressiondo();if (sym == rparen){WordAnalyse();lp--;if(getsym()==-1){return -1;}if(sym!=times&&sym!=slash&&sym!=plus&&sym!=minus) {err++;if(err==1) printf("语法错误: \n");printf("括号后没有跟上+-*\\ \n");}}else{err++;if(err==1) printf("语法错误: \n");printf("error----Needs Rparen \n");}}}return 0;}int term(){factordo();if(sym!=times&&sym!=slash&&sym!=plus&&sym!=minus&&sym!=ident&&sym!=number&&sym!=lparen&&sym!=rparen) {err++;if(err==1) printf("语法错误: \n");printf("不能识别字符\n");}while ((sym == times) || (sym == slash)){WordAnalyse();if(getsym()==-1){err++;if(err==1) printf("语法错误: \n");printf("* \\ 后缺项\n");return -1;}factordo();}return 0;}int expression(){if ((sym == plus) || (sym == minus)){//cout<<strlen(id)<<endl;< p="">if (sym==minus&&2==strlen(ID)+1)flg=1;else{flg=0;WordAnalyse();}getsymdo;termdo();}else{//WordAnalyse();termdo();}if(sym!=times&&sym!=slash&&sym!=plus&&sym!=minus &&sym!=ident&&sym!=number&&sym!=lparen&&sym!=rparen){err++;if(err==1) printf("语法错误: \n");printf("不能识别字符\n");}while ((sym == plus) || (sym == minus)){WordAnalyse();if(getsym()==-1){err++;if(err==1) printf("语法错误: \n");printf("+ - 后缺项\n");return -1;}termdo();}return 0;}int main(int argc, char* argv[]){init();err=0;ifstream fin("in.txt");ofstream fout("out.txt");ch=' ';lp=0;getsymdo;expression();if(err==0) cout<<"语法正确"<<endl;< p="">elsecout<<"语法错误,错误个数: "<<err<<=""></err< </endl;<></strlen(id)<<endl;<>。

《编译原理(实验部分)》实验2_PL0词法分析

《编译原理(实验部分)》实验2_PL0词法分析

《编译原理》(实验部分)实验2_PL0 词法分析一、实验目的加深和巩固对于词法分析的了解和掌握;初步认识PL/0 语言的基础和简单的程序编写;通过本实验能够初步的了解和掌握程序词法分析的整个过程;提高自己上机和编程过程中处理具体问题的能力。

二、实验设备1、P C兼容机一台;操作系统为WindowsWindowsX P2、Visual C++ 6.0 或以上版本,Windows 2000 或以上版本,汇编工具 (在Software 子目录下)。

三、实验原理PL/O语言的编译程序,是用高级语言PASCAL语言书写的。

整个编译过程是由一些嵌套及并列的过程或函数完成。

词法分析程序是独立的过程GETSY完成,供语法分析读单词时使用。

四、实验步骤阅读所给出的词法分析程序( pl0_lexical.c ),搞懂程序中每一个变量的含义,以及每一个过程的作用,并在该过程中进行中文注释;阅读完程序后,画出各过程的流程图;给出的程序包含两处输入错误,利用所给的pl/0 源程序(test.pl0) 对程序进行调试,使其能正确对所给文件进行分析并能够解释运行;在阅读懂所给出的词法分析程序后,将你对词法分析的理解写在实验报告上。

实验代码#include<stdio.h>main(){ printf ("my name is 08061118 yuchaofeng ");}主程序:#include <stdio.h>#include <ctype.h>#include <alloc.h>#include <stdlib.h>#include <string.h>#define NULL 0FILE *fp;char cbuffer;char *key[8]={"DO","BEGIN","ELSE","END","IF","THEN","VAR","WHILE"}; char *border[6]={",",";",":=",".","(",")"};char *arithmetic[4]={"+","-","*","/"};char *relation[6]={"<","<=","=",">",">=","<>"};char *consts[20];char *label[20];int constnum=0,labelnum=0;int search(char searchchar[],int wordtype){int i=0;switch (wordtype) {case 1:for (i=0;i<=7;i++){if (strcmp(key[i],searchchar)==0)return(i+1);};case 2:{for (i=0;i<=5;i++){if (strcmp(border[i],searchchar)==0)return(i+1);};return(0);}case 3:{for (i=0;i<=3;i++){ if (strcmp(arithmetic[i],searchchar)==0){};};return(0);};case 4:{for (i=0;i<=5;i++){ if (strcmp(relation[i],searchchar)==0){return(i+1);};};return(0);};case 5:{for (i=0;i<=constnum;i++){ if (strcmp(consts[i],searchchar)==0){return(i+1);};}consts[i-1]=(char *)malloc(sizeof(searchchar));strcpy(consts[i-1],searchchar);constnum++;return(i);};case 6:{for (i=0;i<=labelnum;i++){ if (strcmp(label[i],searchchar)==0){ return(i+1);};}label[i-1]=(char *)malloc(sizeof(searchchar)); strcpy(label[i-1],searchchar);return(i);};}}char alphaprocess(char buffer){int atype;int i=-1;char alphatp[20];while ((isalpha(buffer))||(isdigit(buffer))){ alphatp[++i]=buffer; buffer=fgetc(fp);}; alphatp[i+1]='\0';if (atype=search(alphatp,1)) printf("%s (1,%d)\n",alphatp,atype-1); else { atype=search(alphatp,6);printf("%s (6,%d)\n",alphatp,atype-1); };return(buffer);char digitprocess(char buffer){int i=-1;char digittp[20];int dtype;while ((isdigit(buffer))){ digittp[++i]=buffer;buffer=fgetc(fp);}digittp[i+1]='\0';dtype=search(digittp,5);printf("%s (5,%d)\n",digittp,dtype-1); return(buffer);}char otherprocess(char buffer){int i=-1;char othertp[20];int otype,otypetp;othertp[0]=buffer;othertp[1]='\0';if (otype=search(othertp,3)){printf("%s (3,%d)\n",othertp,otype-1);buffer=fgetc(fp);goto out;};if (otype=search(othertp,4)){buffer=fgetc(fp);othertp[1]=buffer;othertp[2]='\0';if (otypetp=search(othertp,4)){printf("%s (4,%d)\n",othertp,otypetp-1); goto out;}elseothertp[1]='\0';printf("%s (4,%d)\n",othertp,otype-1);goto out;};if (buffer==':'){ buffer=fgetc(fp);if (buffer=='=')printf(":= (2,2)\n");buffer=fgetc(fp);goto out;}else{if (otype=search(othertp,2)){ printf("%s (2,%d)\n",othertp,otype-1); buffer=fgetc(fp); goto out;}};if ((buffer!='\n')&&(buffer!=' '))printf("%c error,not a word\n",buffer); buffer=fgetc(fp);out: return(buffer);} void main(){ int i;for (i=0;i<=20;i++){label[i]=NULL; consts[i]=NULL;};if ((fp=fopen("skh.c","r"))==NULL) printf("error");else{ cbuffer = fgetc(fp);while (cbuffer!=EOF){if (isalpha(cbuffer)) cbuffer=alphaprocess(cbuffer);else if (isdigit(cbuffer))cbuffer=digitprocess(cbuffer); else cbuffer=otherprocess(cbuffer); };printf("over\n");};}。

PL0词法分析.ppt

PL0词法分析.ppt
1
❖单词的种类: ➢基本字(保留字):BEGIN、 END、 IF、 THEN等 ➢运算符: 如+、-、*、/、:=、#、>=、<=等 ➢标识符: 用户定义的变量名、常数名、过程名 ➢常数: 如10、25、100等整数 ➢界符: 如‘,’、‘.’ 、‘;’ 、‘(’ 、‘)’等 ❖词法分析程序GETSYM所要完成的任务: ➢滤空格、识别保留字 ➢识别标识符、拼数 ➢拼复合词、输出源程序
§2.3 PL/O编译程序的词法分析
❖PL/O词法分析程序功能:为语法语义分析提供单词,把输 入的字符串形式的源程序分割成一个个单词符号传递给语法 语义分析
❖PL/O编译程序设置的三个全程变量: ➢SYM:存放单词的类别,如beginsym, ident, number ➢ID: 存放用户所定义的标识符的值 ➢NUM:存放用户定义的数
2
❖PL/O的词法分析过程GETSYM,YM
4
❖取字符过程GETCH:
图 2.6 取字符过程GETCH
5

实验一 词法分析程序的设计与实现

实验一  词法分析程序的设计与实现

实验一词法分析程序的设计与实现一、实验内容【实验目的和要求】设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解。

【实验内容】通过对PL/0词法分析程序(GETSYM)的分析,并在此基础上按照附录A中给出的PL/0语言的语法描述,编写一个PL/0语言的词法分析程序。

此程序应具有如下功能:输入为字符串(待进行词法分析的源程序),输出为单词串,即由(单词、类别)所组成的二元组序列。

有一定检查错误的能力,例如发现2A这类不能作为单词的字符串。

【实验环境】Windows PC机,任何语言。

【提交内容】提交实验报告,报告内容如下:目的要求、算法描述、程序结构、主要变量名说明、程序清单、调试情况、设计技巧、心得体会。

提交源程序和可执行文件。

【学时】4课时。

二、实验说明词法分析程序的任务就是扫描源程序,依据词法规则识别单词并报告构词错误信息。

通常将单词分为5种类型。

1)基本字:也叫关键字、保留字,是程序设计语言用来表示特定语法含义的一种标识符,如if、begin等。

2)运算符:如+、-、*、/、:=、>、<等。

3)标识符:用户定义的变量名、常数名、函数名等。

不同的高级程序设计语言对关键字是否可以作为普通标识符有不同的要求,有的语言允许程序员使用关键字作为普通标识符,有的程序设计语言则不允许程序员将关键字用着普通标识符(如C/C++、Pascal等都不允许)。

在允许程序员将关键字用作普通标识符的程序设计语言的编译器中,编译器必须具备能够区分一个标识符到底是关键字还是普通标识符的功能。

4)常数:如23、6等。

5)界符:如“,”、“;”、“(”、“)”、“.”等。

注意事项●空格的作用仅仅是将一个个单词分割开来,源程序中的空格不具备别的语法意义,在语法分析及其后续阶段都没有任何作用,因此,词法分析的另一个工作是过滤空格。

●注释对整个源程序的编译也没有任何语法意义,只是为了便于阅读和交流,因此,有的编译程序的词法分析程序也负责过滤注释。

编译原理实验--词法分析器

编译原理实验--词法分析器

实验一词法分析器设计【实验目的】1.熟悉词法分析的基本原理,词法分析的过程以及词法分析中要注意的问题。

2.复习高级语言,进一步加强用高级语言来解决实际问题的能力。

3.通过完成词法分析程序,了解词法分析的过程。

【实验内容】用C语言编写一个PL/0词法分析器,为语法语义分析提供单词,使之能把输入的字符串形式的源程序分割成一个个单词符号传递给语法语义分析,并把分析结果(基本字,运算符,标识符,常数以及界符)输出。

【实验流程图】【实验步骤】1.提取pl/0文件中基本字的源代码while((ch=fgetc(stream))!='.'){int k=-1;char a[SIZE];int s=0;while(ch>='a' && ch<='z'||ch>='A' && ch<='Z'){if(ch>='A' && ch<='Z') ch+=32;a[++k]=(char)ch;ch=fgetc(stream);}for(int m=0;m<=12&&k!=-1;m++)for(int n=0;n<=k;n++){if(a[n]==wsym[m][n]) ++s;else s=0;if(s==(strlen(wsym[m]))) {printf("%s\t",wsym[m]);m=14;n=k+1;} }2.提取pl/0文件中标识符的源代码while((ch=fgetc(stream))!='.'){int k=-1;char a[SIZE]=" ";int s=0;while(ch>='a' && ch<='z'||ch>='A' && ch<='Z'){if(ch>='A' && ch<='Z') ch+=32;a[++k]=(char)ch;ch=fgetc(stream);}for(int m=0;m<=12&&k!=-1;m++)for(int n=0;n<=k;n++){if(a[n]==wsym[m][n]) ++s;else s=0;if(s==(strlen(wsym[m]))) {m=14;n=k+1;}}if(m==13) for(m=0;a[m]!=NULL;m++) printf("%c ",a[m]);3.提取pl/0文件中常数的源代码while((ch=fgetc(stream))!='.'){while(ch>='0' && ch<='9'){num=10*num+ch-'0';ch=fgetc(stream);}if(num!=0) printf("%d ",num);num=0;}4.提取pl/0文件中运算符的源代码int ch=fgetc(stream);while(ch!='.'){switch(ch){case'+': printf("+ ");break;case'-': printf("- ");break;case'*': printf("* ");break;case'/': printf("/ ");break;case'>': if(fgetc(stream)=='=')printf(">= "); else printf("> ");break;case'<': if(fgetc(stream)=='=')printf("<= "); else printf("< ");break;case':': printf(":= ");break;case'#': printf("# ");break;case'=': printf("= ");break;default: break;}ch=fgetc(stream);5.提取pl/0文件中界符的源代码int ch=fgetc(stream);while(ch!='.'){switch(ch){case',': printf(", ");break;case';': printf("; ");break;case'(': printf("( ");break;case')': printf(") ");break;default: break;}ch=fgetc(stream);}【实验结果】1.pl/0文件(222.txt)内容const a=10;var b,c;procedure p;beginc:=b+a;end;beginread(b);while b#0 dobegincall p;write(2*c);read(b)endend .2.实验运行结果【实验小结】1.了解程序在运行过程中对词法分析,识别一个个字符并组合成相应的单词,是机器能过明白程序,定义各种关键字,界符。

词法分析程序(C语言编写,针对PL_0语言)

词法分析程序(C语言编写,针对PL_0语言)

#include <stdio.h>#include <stdlib.h>#include <string.h>#define NORW 13 /* of reserved words */#define TXMAX 100 /* length of identifier table */#define NMAX 14 /* max number of digits in numbers */#define AL 10 /* length of identifiers */#define AMAX 2047 /* maxinum address */#define LEVMAX 3 /* max depth of block nesting */#define CXMAX 200 /* size of code array */#define STACKSIZE 500char *symbol[32]= {"nul","ident","number","plus","minus","times","slash","oddsym","eql","neq","lss","leq","gtr","geq","lparen","rparen","comma","semicolon","period","becomes","beginsym","endsym","ifsym","thensym","whilesym","writesym","readsym","dosym","callsym","constsym","varsym","procsym"}; /* type of symbols */c har *word[NORW]={"begin","call","const","do","end","if","odd","procedure","read","then","var","while","write"}; /* table of reserved words */ char *wsym[NORW]={ "beginsym","callsym","constsym","dosym","endsym","ifsym", "oddsym","procsym","readsym","thensym","varsym","whilesym","writesym"};char *mnemonic[8]= {"lit","opr","lod","sto","cal","ini","jmp","jpc"};char ch; /* last char read */char id[AL+1]; /*last identifier read */char sym[10]; /* last symbol read */char line[81];char a[AL+1],fname[AL+1];enum object{constant,variable,procedur};enum object kind;enum fct{lit,opr,lod,sto,cal,ini,jmp,jpc};enum listswitcher{false,true}; /*true set list object code */enum listswitcher listswitch;FILE *fa;FILE *fa1, *fa2;FILE *fin, *fout;int num; /* last number read */int cc; /* character count */int ll; /* line length */int cx; /* code allocation index */int err;int lev=0,tx=0,dx=3;int linecnt=0;struct instruction{enum fct f; /* function code */int l; /* level */int a; /* displacement addr */}; /* lit 0,a: load constant aopr 0,a: execute opr alod l,a: load variable 1, asto l,a: store variable 1, acal l,a: call procedure a at level 1int 0,a: increment t-register by ajmp 0,a: jump to ajpc 0,a: jump conditional to a */ struct instruction code[CXMAX+1];struct table1{char name[AL+1];enum object kind;int val,level,adr,size;};struct table1 table[TXMAX+1];struct node{c har *pa[32];}*declbegsys,*statbegsys,*facbegsys,*tempsetsys; int in(str, set)char *str;struct node *set;{i nt i=0;w hile(set->pa[i]!=NULL){if(strcmp(str,set->pa[i])==0)return( 1 );elsei++;}r eturn( 0 );}struct node *add(set1,set2)struct node *set1,*set2;{i nt i=0,j=0,k=0,cnt;s truct node *pt;p t=(struct node *)malloc(sizeof(struct node));f or(cnt=0; cnt < 32; cnt++)pt->pa[cnt]=(char*)malloc(10*sizeof(char));w hile(set1->pa[i]!=NULL)strcpy(pt->pa[j++],set1->pa[i++]);w hile(set2->pa[k]!=NULL){if (in(set2->pa[k],set1)==0)strcpy(pt->pa[j++],set2->pa[k++]);elsek++;}p t->pa[j]=NULL;r eturn( pt );}error(int n){i nt i;p rintf ("***");f puts ("***", fa1);f or (i=0;i<cc;i++){printf (" ");}f or (i=0;i<cc;i++){fputs (" ",fa1);}p rintf ("error%d\n",n);f printf (fa1, "error%d\n",n);e rr=err+1;}void get_ch( ){i f (cc==ll+1){if (feof(fin)){printf ("program incomplete");}ll= 0;cc= 0;while ((!feof(fin)) && ((ch=fgetc(fin))!='\n')){putchar(ch);fputc(ch,fa1);line[ll++]=ch;}printf ("\n");line[ll]=ch;fprintf (fa1,"\n");}c h=line[cc++];}void getsym( ){i nt i,j,k;w hile(ch==' '||ch=='\t'||ch=='\n')get_ch( );i f (ch>='a'&&ch<='z'){ /* id or reserved word */k=0;do {if(k<AL){a[k]=ch;k=k+1;}get_ch( );}while((ch>='a'&&ch<='z')||(ch>='0'&&ch<='9'));a[k]='\0';strcpy(id,a);i=0;j=NORW-1;do { /* look up reserved words by binary search */k=(i+j)/2;if (strcmp(id,word[k])<=0) j=k-1;if (strcmp(id,word[k])>=0) i=k+1;}while (i<=j);if (i-1>j) strcpy(sym,wsym[k]);else strcpy(sym,"ident");}e lse if (ch>='0'&&ch<='9'){ /* number */k=0;num=0;strcpy(sym,"number");do {num=10*num+(int)ch-'0';k=k+1;get_ch( );}while(ch>='0'&&ch<='9');if(k>NMAX) error(30);}e lse if (ch==':'){get_ch( );if (ch=='='){strcpy(sym,"becomes");get_ch( );}else strcpy(sym,"nul");}e lse if (ch=='<'){get_ch( );if (ch=='='){strcpy(sym,"leq");get_ch( );}else strcpy(sym,"lss");}e lse if (ch=='>'){get_ch( );if (ch=='='){strcpy(sym,"geq");get_ch( );}else strcpy(sym,"gtr");}e lse {switch(ch){case '+': strcpy(sym,"plus");break;case '-': strcpy(sym,"minus");break;case '*': strcpy(sym,"times");break;case '/': strcpy(sym,"slash");break;case '(': strcpy(sym,"lparen");break;case ')': strcpy(sym,"rparen");break;case '=': strcpy(sym,"eql");break;case ',': strcpy(sym,"comma");break;case '.': strcpy(sym,"period");break;case '#': strcpy(sym,"neq");break;case ';': strcpy(sym,"semicolon");break;}get_ch( );}}void gen(x,y,z)enum fct x;int y,z;{i f (cx>CXMAX){printf("program too long");}c ode[cx].f=x;c ode[cx].l=y;c ode[cx].a=z;c x++;}void test(s1,s2,n)struct node *s1,*s2;int n;{i f (in(sym,s1)==0){error(n);s1=add(s1,s2);while(in(sym,s1)==0) getsym( );}}void enter(k) /* enter object into table */ enum object k;{t x=tx+1;s trcpy(table[tx].name,id);t able[tx].kind=k;s witch(k){case constant:if (num>NMAX){error(31);num=0;}table[tx].val=num;break;case variable:table[tx].level=lev;table[tx].adr=dx;dx++;break;case procedur:table[tx].level=lev;break;}}int position(id) /* find identifier in table */ char id[10];{i nt i;s trcpy(table[0].name,id);i=tx;w hile (strcmp(table[i].name,id)!=0)i--;r eturn i;}void constdeclaration( ){i f (strcmp(sym,"ident")==0){getsym( );if (strcmp(sym,"eql")==0||strcmp(sym,"becomes")==0){if (strcmp(sym,"becomes")==0) error(1);getsym( );if (strcmp(sym,"number")==0){enter(constant);getsym( );}else error(2);}else error(3);}e lse error(4);}void vardeclaration( ){i f (strcmp(sym,"ident")==0){enter(variable);getsym( );}e lse error(4);}void listcode(int cx0) /* list code generated for this block */ {i nt i;i f (listswitch==true){for(i=cx0;i<=cx-1;i++){printf("%2d %5s %3d %5d\n",i,mnemonic[(int)code[i].f],code[i].l,code[i].a);fprintf(fa,"%2d %5s %3d %5d\n",i,mnemonic[(int)code[i].f],code[i].l,code[i].a);}}}void factor(fsys)struct node *fsys;{v oid expression( );i nt m=0,n=0,i;c har *tempset[ ]={"rparen",NULL};s truct node *temp;t emp=(struct node *)malloc(sizeof(struct node));w hile(tempset[m]!=NULL)temp->pa[n++]=tempset[m++];t emp->pa[n]=NULL;t est(facbegsys,fsys,24);w hile(in(sym,facbegsys)==1){if (strcmp(sym,"ident")==0){i=position(id);if (i==0) error(11);else switch(table[i].kind){case constant: gen(lit,0,table[i].val);break; /*some thing error here(lev)*/ case variable: gen(lod,lev-table[i].level,table[i].adr);/*must use para pass in*/break;case procedur: error(21);break;}getsym( );}else if (strcmp(sym,"number")==0){if (num>AMAX){error(31);num=0;}gen(lit,0,num);getsym( );}else if (strcmp(sym,"lparen")==0){getsym( );expression(add(temp,fsys));if (strcmp(sym,"rparen")==0) getsym( );else error(22);}test(fsys,facbegsys,23);}}void term(fsys)struct node *fsys;{i nt i=0,j=0;c har mulop[10];c har *tempset[ ]={"times","slash",NULL};s truct node *temp;t emp=(struct node *)malloc(sizeof(struct node));w hile(tempset[i]!=NULL)temp->pa[i++]=tempset[j++];t emp->pa[i]=NULL;f actor(add(temp,fsys));w hile (in(sym,temp)==1){strcpy(mulop,sym);getsym( );factor(add(temp,fsys));if (strcmp(mulop,"times")==0) gen(opr,0,4);else gen(opr,0,5);}}void expression(fsys)struct node *fsys;{i nt m=0,n=0;c har addop[10];c har *tempset[ ]={"plus","minus",NULL};s truct node *temp;t emp=(struct node *)malloc(sizeof(struct node));w hile(tempset[m]!=NULL)temp->pa[n++]=tempset[m++];t emp->pa[n]=NULL;i f(in(sym,temp)==1){strcpy(addop,sym);getsym( );term(add(fsys,temp));if (strcmp(addop,"minus")==0) gen(opr,0,1);}e lse term(add(fsys,temp));w hile (in(sym,temp)==1){strcpy(addop,sym);getsym( );term(add(fsys,temp));if (strcmp(addop,"plus")==0) gen(opr,0,2);else gen(opr,0,3);}}void condition(fsys)struct node *fsys;{i nt i=0,j=0;c har relop[10];c har *tempset[ ]={"eql","neq","lss","leq","gtr","geq",NULL}; s truct node *temp;t emp=(struct node *)malloc(sizeof(struct node));w hile(tempset[i]!=NULL)temp->pa[j++]=tempset[i++];t emp->pa[j]=NULL;i f (strcmp(sym,"oddsym")==0){getsym( );expression(fsys);gen(opr,0,6);}e lse {expression(add(temp,fsys));if (in(sym,temp)==0) error(20);else {strcpy(relop,sym);getsym( );expression(fsys);if(strcmp(relop,"eql")==0) gen(opr,0,8);if(strcmp(relop,"neq")==0) gen(opr,0,9);if(strcmp(relop,"lss")==0) gen(opr,0,10);if(strcmp(relop,"geq")==0) gen(opr,0,11);if(strcmp(relop,"gtr")==0) gen(opr,0,12);if(strcmp(relop,"leq")==0) gen(opr,0,13);}}}void statement(fsys,plev)struct node *fsys;int plev;{i nt i,cx1,cx2,m=0,n=0;c har *tempset1[ ]={"rparen","comma",NULL};c har *tempset2[ ]={"thensym","dosym",NULL};c har *tempset3[ ]={"semicolon","endsym",NULL};c har *tempset4[ ]={"semicolon",NULL};c har *tempset5[ ]={"dosym",NULL};c har *tempset6[ ]={NULL};s truct node *temp1,*temp2,*temp3,*temp4,*temp5,*temp6; t emp1=(struct node *)malloc(sizeof(struct node));t emp2=(struct node *)malloc(sizeof(struct node));t emp3=(struct node *)malloc(sizeof(struct node));t emp4=(struct node *)malloc(sizeof(struct node));t emp5=(struct node *)malloc(sizeof(struct node));t emp6=(struct node *)malloc(sizeof(struct node));w hile(tempset1[m]!=NULL)temp1->pa[n++]=tempset1[m++];t emp1->pa[n]=NULL;m=0;n=0;w hile(tempset2[m]!=NULL)temp2->pa[n++]=tempset2[m++];t emp2->pa[n]=NULL;m=0;n=0;w hile(tempset3[m]!=NULL)temp3->pa[n++]=tempset3[m++];t emp3->pa[n]=NULL;m=0;n=0;w hile(tempset4[m]!=NULL)temp4->pa[n++]=tempset4[m++];t emp4->pa[n]=NULL;m=0;n=0;w hile(tempset5[m]!=NULL)temp5->pa[n++]=tempset5[m++];t emp5->pa[n]=NULL;m=0;n=0;w hile(tempset6[m]!=NULL)temp6->pa[n++]=tempset6[m++];t emp6->pa[n]=NULL;m=0;n=0;i f (strcmp(sym,"ident")==0){i=position(id);if (i==0)error(11);else {if (table[i].kind!=variable){error(12);i=0;}}getsym( );if (strcmp(sym,"becomes")==0) getsym( );else error(13);expression(fsys);if (i!=0)gen(sto,plev-table[i].level,table[i].adr);}e lse if (strcmp(sym,"readsym")==0){getsym( );if (strcmp(sym,"lparen")!=0) error(24);else {do{getsym( );if (strcmp(sym,"ident")==0) i=position(id);else i=0;if (i==0) error(35);else {gen(opr,0,16);gen(sto,plev-table[i].level,table[i].adr);}getsym( );}while(strcmp(sym,"comma")==0);}if (strcmp(sym,"rparen")!=0) {error(22);while(in(sym,fsys)==0) getsym( );}else getsym( );}e lse if (strcmp(sym,"writesym")==0){getsym( );if (strcmp(sym,"lparen")==0){do{getsym( );expression(add(temp1,fsys));gen(opr,0,14);}while(strcmp(sym,"comma")==0);if (strcmp(sym,"rparen")!=0) error(33);else getsym( );}gen(opr,0,15);}e lse if (strcmp(sym,"callsym")==0){getsym( );if (strcmp(sym,"ident")!=0) error(14);else {i=position(id);if (i==0) error(11);else {if (table[i].kind==procedur)gen(cal,plev-table[i].level,table[i].adr);else error(15);}getsym( );}}e lse if (strcmp(sym,"ifsym")==0){getsym( );condition(add(temp2,fsys));if (strcmp(sym,"thensym")==0) getsym( );else error(16);cx1=cx;gen(jpc,0,0);statement(fsys,plev);code[cx1].a=cx;}e lse if (strcmp(sym,"beginsym")==0){getsym( );statement(add(temp3,fsys),plev);while(in(sym,add(temp4,statbegsys))==1){if (strcmp(sym,"semicolon")==0) getsym( );else error(10);statement(add(temp3,fsys),plev);}if (strcmp(sym,"endsym")==0) getsym( );else error(17);}e lse {if (strcmp(sym,"whilesym")==0){cx1=cx;getsym( );condition(add(temp5,fsys));cx2=cx;gen(jpc,0,0);if (strcmp(sym,"dosym")==0) getsym( );else error(18);statement(fsys,plev);gen(jmp,0,cx1);code[cx2].a=cx;}}t est(fsys,temp6,19);}void block(plev,fsys)int plev;struct node *fsys;{i nt m=0,n=0;i nt dx0=3; /* data allocation index */ i nt tx0; /* initial table index */i nt cx0; /* initial code index */c har *tempset1[ ]={"semicolon","endsym",NULL};c har *tempset2[ ]={"ident","procsym",NULL};c har *tempset3[ ]={"semicolon",NULL};c har *tempset4[ ]={"ident",NULL};c har *tempset5[ ]={NULL};s truct node *temp1,*temp2,*temp3,*temp4,*temp5;t emp1=(struct node *)malloc(sizeof(struct node));t emp2=(struct node *)malloc(sizeof(struct node));t emp3=(struct node *)malloc(sizeof(struct node));t emp4=(struct node *)malloc(sizeof(struct node));t emp5=(struct node *)malloc(sizeof(struct node));w hile(tempset1[m]!=NULL)temp1->pa[n++]=tempset1[m++];t emp1->pa[n]=NULL;m=0;n=0;w hile(tempset2[m]!=NULL)temp2->pa[n++]=tempset2[m++];t emp2->pa[n]=NULL;m=0;n=0;w hile(tempset3[m]!=NULL)temp3->pa[n++]=tempset3[m++];t emp3->pa[n]=NULL;m=0;n=0;w hile(tempset4[m]!=NULL)temp4->pa[n++]=tempset4[m++];t emp4->pa[n]=NULL;m=0;n=0;w hile(tempset5[m]!=NULL)temp5->pa[n++]=tempset5[m++];t emp5->pa[n]=NULL;m=0;n=0;l ev=plev;t x0=tx;t able[tx].adr=cx;g en(jmp,0,1);i f (plev>LEVMAX) error(32);d o{if (strcmp(sym,"constsym")==0){getsym( );do{constdeclaration( );while(strcmp(sym,"comma")==0){getsym( );constdeclaration( );}if (strcmp(sym,"semicolon")==0) getsym( );else error(5);}while(strcmp(sym,"ident")==0);}if (strcmp(sym,"varsym")==0){getsym( );do{dx0++;vardeclaration( );while (strcmp(sym,"comma")==0){getsym( );dx0++;vardeclaration( );}if (strcmp(sym,"semicolon")==0) getsym( );else error(5);}while(strcmp(sym,"ident")==0);}while (strcmp(sym,"procsym")==0){getsym( );if (strcmp(sym,"ident")==0){enter(procedur);getsym( );}else error(4);if (strcmp(sym,"semicolon")==0) getsym( );else error(5);block(plev+1,add(temp3,fsys));lev=lev-1;if (strcmp(sym,"semicolon")==0){getsym( );test(add(statbegsys,temp2),fsys,6);}else error(5);}test(add(statbegsys,temp4),declbegsys,7);}while(in(sym,declbegsys)==1);c ode[table[tx0].adr].a=cx;t able[tx0].adr=cx;t able[tx0].size=dx0;c x0=cx;g en(ini,0,dx0);s tatement(add(temp1,fsys),plev);g en(opr,0,0);t est(fsys,temp5,8);l istcode(cx0);}int base(l,b,s)int l;int *b;int s[STACKSIZE];{int b1;b1=*b; /*find base l level down */ while(l>0){b1=s[b1];l=l-1;}return b1;}void interpret( ){i nt p=0; /* p:program register*/ i nt b=1; /* b:base register*/i nt t=0; /* t:topstack registers */ s truct instruction i;i nt s[STACKSIZE]; /* datastore */p rintf("start pl0\n");s[0]=0;s[1]=0;s[2]=0;s[3]=0;d o{i=code[p];p=p+1;switch(i.f){case lit: t=t+1;s[t]=i.a;break;case opr:switch(i.a){ /*operator*/case 0: t=b-1; /*return*/p=s[t+3];b=s[t+2];break;case 1: s[t]=-s[t];break;case 2: t=t-1; /*plus*/s[t]=s[t]+s[t+1];break;case 3: t=t-1; /*minus*/s[t]=s[t]-s[t+1];break;case 4: t=t-1; /*times*/s[t]=s[t]*s[t+1];break;case 5: t=t-1;s[t]=s[t]/s[t+1];break;case 6: if (s[t]%2==0) s[t]=0;else s[t]=1;break;case 8: t=t-1;if (s[t]==s[t+1]) s[t]=1;else s[t]=0;break;case 9: t=t-1;if (s[t]==s[t+1]) s[t]=0;else s[t]=1;break;case 10:t=t-1;if (s[t]<s[t+1]) s[t]=1;else s[t]=0;break;case 11:t=t-1;if (s[t]>=s[t+1]) s[t]=1;else s[t]=0;break;case 12:t=t-1;if (s[t]>s[t+1]) s[t]=1;else s[t]=0;break;case 13:t=t-1;if (s[t]<=s[t+1]) s[t]=1;else s[t]=0;break;case 14:printf("%d",s[t]);fprintf(fa2,"%d",s[t]);t=t-1;break;case 15:printf("\n");fprintf(fa2,"\n");break;case 16:t=t+1;printf("?");fprintf(fa2,"?");scanf("%d",&s[t]);fprintf(fa2,"%d",s[t]);break;}break;case lod: t=t+1;s[t]=s[base(i.l,&b,s)+i.a];break;case sto: s[base(i.l,&b,s)+i.a]=s[t]; /*ptrintf("%d",s[t])*/t=t-1;break;case cal: s[t+1]=base(i.l,&b,s); /*generate new block mark */ s[t+2]=b;s[t+3]=p;b=t+1;p=i.a;break;case ini:t=t+i.a;break;case jmp:p=i.a;break;case jpc:if (s[t]==0) p=i.a;t=t-1;break;}}while(p!=0);f close(fa2);}main( ){i nt m=0,n=0;c har *declbeg[ ]={"constsym","varsym","procsym",NULL};c har *statbeg[ ]={"beginsym","callsym","ifsym","whilesym",NULL};c har *facbeg[ ]={"ident","number","lparen",NULL};c har *tempset[ ]={"period","constsym","varsym","procsym",NULL};d eclbegsys=(struct node *)malloc(sizeof(struct node));s tatbegsys=(struct node *)malloc(sizeof(struct node));f acbegsys=(struct node *)malloc(sizeof(struct node));t empsetsys=(struct node *)malloc(sizeof(struct node));w hile(declbeg[m]!=NULL)declbegsys->pa[n++]=declbeg[m++];d eclbegsys->pa[n]=NULL;m=0;n=0;w hile(statbeg[m]!=NULL)statbegsys->pa[n++]=statbeg[m++];s tatbegsys->pa[n]=NULL;m=0;n=0;w hile(facbeg[m]!=NULL)facbegsys->pa[n++]=facbeg[m++];f acbegsys->pa[n]=NULL;m=0,n=0;w hile(tempset[m]!=NULL)tempsetsys->pa[n++]=tempset[m++];t empsetsys->pa[n]=NULL;i f((fa1=fopen("fa1.txt","w"))==NULL){printf("Cannot open file\n");exit( 0 );}p rintf("Input file?\n");f printf(fa1,"Input file?\n");s canf("%s",fname);f printf(fa1,"%s",fname);i f((fin=fopen(fname,"r"))==NULL){printf("Cannot open file according to given filename\n");exit( 0 );}p rintf("list object code?\n");s canf("%s",fname);f printf(fa1,"list object code?\n");i f (fname[0]=='y')listswitch=true;e lselistswitch=false;e rr=0;c c=1; cx=0; ll=0;c h=' ';g etsym( );i f((fa=fopen("fa.txt","w"))==NULL){printf("Cannot open fa.txt file\n");exit( 0 );}i f((fa2=fopen("fa2.txt","w"))==NULL){printf("Cannot open fa2.txt file\n");exit( 0 );}b lock(0,add(statbegsys,tempsetsys));f close(fa);f close(fa1);i f (strcmp(sym,"period")!=0)error(9);i f (err==0)interpret( );elseprintf("%d errors in PASCAL program\n",err);f close (fin);}。

实验一 PL O语言的词法分析程序GETSYM

实验一 PL O语言的词法分析程序GETSYM

实验一PL O语言的词法分析程序GETSYM一、实验目的加深和巩固对于词法分析的了解和掌握;初步认识PL/0语言的基础和简单的程序编写;通过本实验能够初步的了解和掌握程序词法分析的整个过程;提高自己上机和编程过程中处理具体问题的能力。

二、实验要求实验前先阅读完总体的预备知识以及实验相关的基础知识;要求自己独立完成实验,不得抄袭别人的结果;编写和调试过程中出现的问题做好记录;实验程序调试完成后,用给定的PL0测试程序(test.pl0)进行测试,由老师检查测试结果,并给予相应的成绩;实验完成后,要上交实验报告。

三、实验原理PL/O语言的编译程序,是用高级语言PASCAL语言书写的。

整个编译过程是由一些嵌套及并列的过程或函数完成。

词法分析程序是独立的过程GETSYM完成,供语法分析读单词时使用。

语法分析是由过程BLOCK完成。

采用自顶向下的递归子程序法。

所产生的目标程序为假象栈式计算机的汇编语言。

对目标程序的执行是由PASCAL语言书写的解释程序进行的。

因此PL/O语言可以在配备PASCAL语言的任何机器上实现。

由于PL/O语言编译程序是适合教学用的实例,它的数据类型只有整形数,数据运算只有四则运算。

语句有复制语句、条件语句、While型循环语句、输入、输出语句和不带参数允许递归调用过程语句及复合语句。

词法分析程序GETSYM的功能包括:1、滤空格,空格在词法分析时是一种不可缺少的界符,而在语法分析时是无用的,所以必须滤掉。

2、识别保留子:设有一张保留字表。

对每个字母打头的字母、数字字符串要查此表。

若查着则为保留字,对应的类别放在SYM中。

如IF对应值为THENSYM。

3、识别标识符:对用户定义的标识符将IDENT放在SYM中,标识符本身的值放在ID中。

4、拼数:当所取单词是数字时,将树的类别NUMBER放在SYM中,数值本身的值放在NUM 中。

5、拼复合词:对两个字符组成的算符如:=、:=、=等单词,识别后将类别送SYM中。

编译原理实践6—PL0的语法分析程序构造

编译原理实践6—PL0的语法分析程序构造

function position(id:alfa):integer; var i:integer; begin(* find identifier id in table *) table[0].name:=id; i:=tx; while table[i].name<>id do i:=i-1; position:=i end(* position *);
编译原理实践 --PL/0的语法分析程序
构造
由语法图到过程调用相关图 从相关图到程序的总体结构 写出每一个语法分析子程序 语法分析程序的扩充 PL/0语法分析程序及其执行
PL/0编译程序在对PL/0源程序编译时, 要经历词法分析、语法分析、出错处理、 代码生成和解释执行一系列过程 自顶向下、逐步扩充、分阶段实施 “结构化程序设计方法”
1. 建立符号表与主程序的扩充 2. 建立error子过程过程和出错信息表 3. 标识符的处理与程序的扩充
4.1建立符号表与主程序的扩充
在主程序的说明部分,对PL/0语言的符 号类型symbol及其取值范围做了说明 在主程序部分,对PL/0语言的所有保留 字相பைடு நூலகம்的符号,以及在词法分析程序 getsym里最后要确定的各个单字符做了 定义
1.由语法图到过程调用相关图
program
condition expression term
block
statement
factor
program PL0; procedure getsym; procedure getch; getch; getsym; procedure procedure procedure procedure procedure factor;
扩充常量说明、变量说明和过程说明 扩充涉及调用标识符的有关赋值语句、 过程调用语句,还有表达式等。

pl0词法分析

pl0词法分析
fprintf(fOut,"P类:\n");
for(i=0;i<p_num;i++)
fprintf(fOut,"name:%stimes:%d\n",P[i].name,P[i].times);
fprintf(fOut,"S类:\n");
for(i=0;i<s_num;i++)
fprintf(fOut,"name:%stimes:%d\n",S[i].name,S[i].times);
}
break;
default:
printf("useage:flex [filename] [filename]\n");
exit(1);
}
yylex();
fprintf(fOut,"K类:\n");
for(i=0;i<k_num;i++)
fprintf(fOut,"name:%stimes:%d\n",K[i].name,K[i].times);
}
break;
case 'O':
for(i=0;i<o_num;i++){
if(strcmp(O[i].name,yytext)==0){
O[i].times++;
flag=0;
break;
}
}
if(flag){
strcpy(O[o_num].name,yytext);O[o_num].times++;o_num++;
exit(1);

PL0语言的词法程序设计

PL0语言的词法程序设计

课程设计报告( 2012--2013年度第一学期)名称:编译技术课程设计题目:PL/0语言的词法程序设计院系:班级:学号:学生姓名:指导教师:设计周数:一周成绩:日期:2013年1 月11日1 课程设计的目的和要求1.1 课程设计的目的本次设计的时间为1周,目的是通过使用高级语言实现部分算法加强对编译技术和理论的理解。

设计的题目要求具有一定的规模,应涵盖本课程内容和实际应用相关的主要技术。

1.2 课程设计的要求1、输入不能通过手动输入,必须通过文件方式输入到程序中2、给定文法和符号串;3、给出该符号串的语法树;4、文法要求可以用文件方式和直接输入两种方法2 系统描述(对相应题目的问题域描述)本次实验使用windows 7的Microsoft Visual C++ 6.0软件,2.1 文法的描述if->X then Y else Y;X->number<number;X-> >>>=;X-> becomes <= becomes;X->sys>=syswordY->end=end;3 概要设计3.1 概要设计(体现系统的设计思路和主要功能)要求:1. 写一个能够完成PL/0语言的词法分析的程序;2. 将源程序文件中的单词识别出该单词是哪一个保留字、或者哪一个符号、或者是标识符、或者是常数;3. 将分析的结果以文件的方式输出;4. 该词法分析程序可以过滤掉多行注释 /* */和单行注释//。

3.2 系统用例图搜索当前符号是否为保留字搜索当前符号是否为单字符符号词法分析,获取一个符号PL/0编译程序词法分析管理员includeincludeinclude图3-1 系统用例图3.3 系统用例【必须有】系统用例图如下图所示搜索当前符号是否为保留字搜索当前符号是否为单字符符号词法分析,获取一个符号PL/0编译程序词法分析includeincludeinclude4 详细设计4.1 系统的主要函数void judgeWord(string str);//搜索当前符号是否为保留字 int judgeSymbol(char ch);//搜索当前符号是否为单字符符号 void getsym();//词法分析,获取一个符号4.2 主要算法的流程图GETSYM滤空CH=#?GETCH YCH 是字母?NCH 是数字?NK :=0Y 拼数,将拼数后的值送NUM SYM :=NUMBERY 把该字符转换成对应的单词,将其与SYM 的对比NK<10?K:=K+1A[K]:=CHGETCHCH 是字母或数字ID ;=AID 是否是保留字?SYM:==IDENT相应保留字符别送SYM返回YNNYNY图4-1 系统流程图GETCH缓冲区是否还有字符源程序文件是否结束读入一个字符记入为CHCH;=CH+1CH;=LINE 【CH 】打印出错信息停止编译返回YNNY图4-2 取字符过程GETCH4.3 数据分析与定义【必须有】//设置单字符符号char symbol[] = {'+','-','*','/','(',')','=',',','.','#',';'}; //设置单字符名称 String ssym[] = {"plus","minus","times","slash","lparen","rparen","eql","comma","peroid","neg","semicolon"}; //设置保留字 String word[] = {"begin","call","const","do","end","if","odd","procedure","read","then","var","while","write"}; //设置保留字符号 String wsym[] = {"beginsym","callsym","constsym","dosym","endsym","ifsym","oddsym","procsym","readsym","th ensym","varsym","whilesym","writesym"};ifstream fin("in.txt");ofstream fout("result.txt");FILE *p=fopen("result.txt","w");void judgeWord(string str);//搜索当前符号是否为保留字int judgeSymbol(char ch);//搜索当前符号是否为单字符符号void getsym();//词法分析,获取一个符号4.4 系统界面设计5 测试方法和测试结果5.1 测试用例1测试目的:是否能正确的分析词法输入const a=101.25;var b,c;procedure p;var d;begind:=20.12;c:=d/a;c:=c+b;end;beginread (b);while b=0 dobegincall p;write(2>=c);read(b);endend.#输出结果如图5-1所示。

pl0词法分析器(C语言版)

pl0词法分析器(C语言版)

#include<stdio.h>#include<string.h>#include<stdlib.h>void init();void getsym();enum symbol {nul,ident,number,plus,minus,times,slash,oddsym,eql,neq, beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym, constsym,varsym,procsym,programsym,};#define norw 14#define al 10#define nmax 10char word [norw][al];char ch;enum symbol sym;enum symbol wsym[norw];enum symbol ssym[256];FILE *fin,*fout;void main(){printf("please input outfile's name:\n");//词法分析之后的结果要输出到的文件}char outname[30],inname[30]; scanf("%s",outname);if((fout=fopen(outname,"w"))==NULL){printf("cannot open output file!");exit(0);}printf("please input infile's name:\n");//需要词法分析的源程序scanf("%s",inname);if((fin=fopen(inname,"r"))==NULL){printf("cannot open file!\n");exit(0);}ch=fgetc(fin);while(ch!=EOF){}getsym();//读取源文件void getsym(){long m;char id[al+1],a[al+1];int i,k;init();if(ch==' '||ch==10||ch==9){}else {if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z'){k=0;ch=fgetc(fin);do {if(k<al){a[k]=ch;k++;}ch=fgetc(fin);}while((ch>='a'&&ch<='z'||ch>='0'&&ch<='9')||(ch>='A'&&ch<='Z'||ch>='0'&&ch<='9') );a[k]=0;strcpy(id,a);for(i=0;i<norw;i++){if(strcmp(id,word[i])==0){sym=wsym[i]; printf("%s %ssym\n",id,id);fprintf(fout,"%s %ssym\n",id,id);break;}else {if(i==(norw-1)){sym=ident;printf("%s ident\n",id);fprintf(fout,"%s ident\n",id);}}}}else {if(ch>='0'&&ch<='9'){k=0;m=0;sym=number;do}{m=10*m+ch-'0';k++;ch=getc(fin);}while(ch>='0'&&ch<='9');if(k>=nmax){printf("error!数值太大!\n");//exit(0);}printf("%d number\n",m);fprintf(fout,"%d number\n",m); else {if(ch==':'){ch=getc(fin);printf(":fprintf(fout,":ch=fgetc(fin);}else {}sym=nul; fprintf(fout,":nul\n");printf(":nul\n");else {if(ch=='<'){ch=fgetc(fin); if(ch=='='){sym=leq;printf("<=lep\n");fprintf(fout,"<=ch=fgetc(fin);}else {sym=lss; printf("<fprintf(fout,"<}}else {if(ch=='>'){ch=fgetc(fin); if(ch=='='){sym=geq;printf(">=fprintf(fout,">=ch=fgetc(fin);}else {sym=gtr;printf(">fprintf(fout,">}}else {sym=ssym[ch];if(ch=='+'){printf("+plus\n");ch=fgetc(fin);}else lep\n");lss\n");lss\n");geq\n");geq\n");gtr\n");gtr\n");plus\n");fprintf(fout,"+if(ch=='-'){printf("-minus\n");fprintf(fout,"-else if(ch=='*'){printf("*times\n");fprintf(fout,"*elseif(ch=='/'){printf("/slash\n");fprintf(fout,"/minus\n");ch=fgetc(fin);} times\n");ch=fgetc(fin);}slash\n");ch=fgetc(fin);}if(ch=='('){printf("(rparen\n");ch=fgetc(fin);}eql\n");ch=fgetc(fin);}neq\n");ch=fgetc(fin);}period\n");ch=fgetc(fin);}semicoln\n");ch=fgetc(fin);}nul\n",ch);ch=fgetc(fin);}}}}}}}}//对关键字等实现初始化void init(){int i;for(i=0;i<=255;i++){elselparen\n");fprintf(fout,"(elseif(ch==')'){printf(")elseif(ch=='='){printf("=elseif(ch==','){printf(",elseif(ch=='#'){printf("#elseif(ch=='.'){printf(".elseif(ch==';'){printf(";else{printf("%c lparen\n");ch=fgetc(fin);}rparen\n");fprintf(fout,")neq\n");fprintf(fout,"#period\n");fprintf(fout,".semicoln\n");fprintf(fout,"; nul\n",ch);fprintf(fout,"%c }ssym[i]=nul;}ssym['+']=plus;ssym['-']=minus;ssym['*']=times;ssym['/']=slash;ssym['(']=lparen;ssym[')']=rparen;ssym['=']=eql;ssym['.']=period;ssym['#']=neq;ssym[';']=semicolon;strcpy(&(word[0][0]),"begin");strcpy(&(word[1][0]),"call");strcpy(&(word[2][0]),"const");strcpy(&(word[3][0]),"do");strcpy(&(word[4][0]),"end");strcpy(&(word[5][0]),"if");strcpy(&(word[6][0]),"odd");strcpy(&(word[7][0]),"procedure");strcpy(&(word[8][0]),"read");strcpy(&(word[9][0]),"program"); strcpy(&(word[10][0]),"var"); strcpy(&(word[11][0]),"whlie"); strcpy(&(word[12][0]),"write"); strcpy(&(word[13][0]),"then"); wsym[0]=beginsym;wsym[1]=callsym;wsym[2]=constsym;wsym[3]=dosym;wsym[4]=endsym;wsym[5]=ifsym;wsym[6]=oddsym;wsym[7]=procsym;wsym[8]=readsym;wsym[9]=programsym;wsym[10]=varsym;wsym[11]=whilesym;wsym[12]=writesym;wsym[13]=thensym;。

PL0语言的词法语法分析器的设计与实现

PL0语言的词法语法分析器的设计与实现

目录1前言............................................................. 错误!未定义书签。

2 PL/0语言描述.................................................... 错误!未定义书签。

PL/0语言的语法描述图........................................... 错误!未定义书签。

PL/0语言文法的EBNF表示........................................ 错误!未定义书签。

3 PL/0语言的词法与语法分析........................................ 错误!未定义书签。

PL/0编译器的词法分析........................................... 错误!未定义书签。

PL/0编译器的语法分析........................................... 错误!未定义书签。

PL/0编译器语法分析进程的直观思想........................... 错误!未定义书签。

PL/0编译器语法分析程序分析................................. 错误!未定义书签。

4 PL/0语言词法与语法分析器的设计.................................. 错误!未定义书签。

5 PL/0语言词法与语法分析器的编程实现.............................. 错误!未定义书签。

编程环境简介.................................................... 错误!未定义书签。

系统硬件设备................................................ 错误!未定义书签。

pl0 词法分析 c程序

pl0 词法分析 c程序
#include <stdio.h>
/*PL/0编译系统C++版本*/
#include "pl0.h"
#include "string.h"
/*解释执行时使用的栈*/
#define stacksize 500
int ty;
void printTokens();
int main()
{
k++;
}
getchdo;
}while(ch>='a'&&ch<='z'||ch>='0'&&ch<='9');
a[k]=0;
strcpy(id,a);
i=0;
j=norw-1;
do{ /*搜索当前符号是否为保留字*/
memset(space,32,81);
space[cc-1]=0;
printf("****%s!%d\n",space,n);
fprintf(fa1,"****%s!%d\n",space,n);
err++;
}
/*
/*
*漏掉空格,读取一个字符。
*
*每次读一行,存入line缓冲区,line被getsym取空后再读一行
//fprintf(fa1,"%d",cx);
ch=' ';
while(ch!=10)
{
if(EOF==fscanf(fin,"%c",&ch))

编译原理实践-PL0的词法分析程序构造

编译原理实践-PL0的词法分析程序构造
编译原理实践-PL0的词法 分析程序构造
通过本次演讲,将带你领略编译原理的奇妙之处,并深入介绍PL0语言的词 法分析及程序构造,让你轻松掌握。
编译原理简介
编译原理是计算机科学的重要基础,涉及源代码的解析、优化和转换过程。它是开发高效程序和语言的 关键。
PL0语言简介
PL0是一种简单且易于学习的编程语言,适合编译原理教学。它具有C语言的 语法特点,是学习编译原理的理想选择。
词法分析的概念和作用
词法分析是编译过程中的第一步,将源代码分解为各种标记(Token)。它有助于语法分析和语义分析的 进行。
PL0的词法规则
PL0的词法规则定义了它的各类标记,如关键字、标识符、运算符和常量。了解规则对于正确理解代码 至关重要。
词法分析程序的设计思路
设词法分析程序需要考虑标识符的判别、关键字的识别等问题。采用有限自动机是一种常用的设计方 法。
PL0的词法分析程序实现
使用C语言编写PL0的词法分析程序,结合有限自动机算法,有效地识别源代 码中的各种标记。
实验结果与总结
通过实验,我们验证了词法分析程序的正确性和性能。深入总结实验结果,对编译原理的学习和应用有 了更深入的理解。

【精品】编写PL0语言词法分析程序c

【精品】编写PL0语言词法分析程序c

编写PL/0语言的词法分析程序要求:1、读入用PL/0语言编写的源程序,正确的进行词法分析,并输出二元式序列.2、若源程序有词法错误,能够给出出错的准确位置。

3、词法代号如下(+,+);(-,—);(*,*);(/,/);((,();(),));(,,,);(;,;);(。

,。

);(#,#); (=,=);(>,〉); (<,<);(:=,a); (〉=,b);(<=,c); (数字,d); (标识符,e); 关键字代号: (begin,f); (call,g);(const,h);(do,i);(end,j);(if,k);(odd,l);(procedure,m);(read,n);(then,o);(var,p);(while,q);(write,r);4、等于运算符号为一个=测试程序:A。

C====================== CONST A=10;VAR B,C; PROCEDURE P;VAR D;PROCEDURE Q;VAR X;BEGINREAD(X);D:=X;WHILE X〈0DO CALL P;END;BEGINWRITE(D);CALL Q;END;BEGINCALL P;END。

*//*program name:chifufenxi*//*作者:小万qq:421404493*//*date:2004.10.11*/#include<stdio.h〉#include〈stdlib.h〉#include<conio.h>#include〈ctype.h〉#include<string。

h〉#define N 256//每一行的字符数不能超过256个char buffer[N]; //用作存放一行字符char word[20]; //用作存放经过分析单词char *kword[13]={"begin",”call",”const”,”do”,"end”,”if”,”odd”,”procedu re”,"read”,”then”,”var",”while",”write”};char ktype[13]={’f',’g','h','i’,’j’,'k',’l’,’m’,’n','o','p',’q',’r'};int len;//记录每一行的长度int count=0;//用来记录行数void write(char *wstr,char wc,FILE *wout)//将分析结果按照规则写入到文件{fputc(’(’,wout);fputs(wstr,wout);fputc(’,',wout);fputc(wc,wout);fputc(')',wout);}int readbuffer(FILE *fp){char ch;len=0;ch=fgetc(fp);while(!feof(fp) &&ch!=’\n’)//读取字符到缓冲区{buffer[len]=ch;ch=fgetc(fp);len++;}len-—;//用来控制词法分析时行分析中字母的个数if(feof(fp))//标志文件是否结束return 0;elsereturn 1;}void error(int type){if(type==1)printf("为无效字符,第%d行词法出错,标志符不能以数字开头\n",count);else if(type==2)printf("第%d行词法出错,赋值符应为\:\= \n ”,count);else printf(”为无效字符,第%d行词法出错\n",count);}void check(char *str,FILE *out);//声明函数,此函数用来分类单词void fenxi(char *row,FILE *op)//此函数用来对每一行的单词进行语法分析{//printf("%d\n",count);int k=0;//用作控制临时存放单词的变量str0int i=0;//定义两个变量用作控制每一行是否结束,int ferror=0;//用作出错标志char str0[20];//临时存放单词的变量while(i〈=len){k=0;//将k置0strcpy(word,”\0");//将存放单词的变量清空/*去除空格*/if(isspace(row[i]))//去出空格,跳格符,换行符{i++;continue;}/*去出无效字符*/while(!isalpha(row[i])&&!isdigit(row[i])&&i<=len&&!isspace(row [i])&&!(row[i]==’\0'||row[i]==’:’||row[i]=='>'||row[i]==’〈’||row[i]==’+’||row[i]=='—' ||row[i]=='*' ||row[i]==’/’||row[i]==’(’|| row[i]==’)’||row[i]==',’||row[i]==’;’||row [i]=='.'||row[i]==’#’|| row[i]==’=’)){putchar(row[i]);ferror=1;//设置错误标志符}if(ferror==1){error(3);//调用出错处理函数ferror=0;}/*对注释进行处理,假设此语言的注释只能单行注释以双斜杠“//”为注释开始标志*/if(row[i]=='/'){if(row[i]==’/’){i=len+1;//忽略注释符后面的单词continue;}elsei--;}/*判断是否为数字*/if(isdigit(row[i])){while(i〈=len&&!isspace(row[i])&&!(row[i]=='\0'||row[i]==':’||row[i]=='〉'||row[i]=='〈'||row[i]==’+’|| row[i]==’—' ||row[i]==’*’|| row[i]=='/' ||row[i]=='(’||row[i]==’)'|| row[i]==',’||row[i]==’;'|| row[i]=='.'|| row[i]==’#’|| row[i]=='=’))//当不到行尾,是数字或字母当然有可能是无效字符{if(isdigit(row[i]))//是数字则将字符逐个存入临时数组{str0[k]=row[i];i++;k++;// putchar('e’);}else //数字中加有字母或无效字符则报错{// putchar(’x’);ferror=1;break;//已经出错设置标志并退出循环}}if(ferror==1)//检测是否出错{/*将刚刚的那个单词后面的数字和字母清空,如123abc123或则123$$23等,当出现错误后,需要消除abc123和$$23 以免误作为下一个标志符*/for(int j=0;j〈k;j++)putchar(str0[j]);while(i〈=len&&!isspace(row[i])&&!(row[i]==’\0’||row[i]==':’||row[i]=='>'||row[i]==’〈'||row[i]=='+’||row [i]=='-’|| row[i]=='*' || row[i]==’/'||row [i]=='(’||row[i]==')' ||row[i]==',’||row[i]==’;’||row[i]==’。

实验一

实验一

实验一词法分析器的实现一、实验目的设计并实现一个PL/0语言(或其它语言的子集,如C语言的子集)的词法分析程序,加深对词法分析原理的理解。

二、实验原理:词法分析是从左向右扫描每行源程序的符号,拼成单词,换成统一的机内表示形式——TOKEN字,送给语法分析程序。

TOKEN字是一个二元式:(单词种别码,自身值)。

PL/0语言单词的种别码用整数表示,可参考教材或自行设定;单词自身值按如下规则给出:1 标识符的自身值是它在符号表的入口地址。

2常数的自身值是常数本身(或它的二进制数值)。

3关键字和界限符的自身值为本身。

三、实验步骤与要求1、要求根据状态图,设计实现词法分析器。

2、编制程序,此程序应具有如下功能:1)输入:字符串(待进行词法分析的源程序),可从键盘直接输入或从文件读入输出:由(种别码,自身值)所组成的二元组序列。

2)功能:a.滤空格b.识别保留字:if then else while do 等c.识别标识符:<字母>(<字母>|<数字>)*d.识别整数数:0 | (1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*e.识别典型的运算符和分隔符,例如 + - * / > >= <= ( ) ;3)具有一定的错误处理功能。

例如,能检查出程序语言的字符集以外的非法字符。

3、可以使用开发工具,自行设计界面,可以自行确定一些附加功能。

4、请指导教师检查程序和运行结果,评定成绩。

评定级别分优秀、良好、合格、不合格。

第一次验收中如果存在问题,老师指出后允许改进,改进后再重新验收。

成绩以最后一次的验收为准。

5、撰写并上交实验报告。

必须提交实验报告,通过此环节训练实验总结与分析的能力。

最后参考实验报告给出实验成绩。

四、上机报告内容1、实验题目、班级、学号、姓名、实验完成日期;(标准封皮可从网上下载);2、对实验题目的理解与说明;3、程序功能与框架;4、设计说明,包括存储结构、主要变量、算法思路等。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

PL/0语言词法分析程序//这是我编译原理的一次作业,中间有许多不足之处希望大家指正/*编写PL/0语言的词法分析程序要求:1、读入用PL/0语言编写的源程序,正确的进行词法分析,并输出二元式序列。

2、若源程序有词法错误,能够给出出错的准确位置。

3、词法代号如下(+,+);(-,-);(*,*);(/,/);((,();(),));(,,,);(;,;);(.,.);(#,#);(=,=);(>,>);(<,<);(:=,a);(>=,b);(<=,c);(数字,d);(标识符,e);关键字代号:(begin,f);(call,g);(const,h);(do,i);(end,j);(if,k);(odd,l); (procedure,m); (read,n);(then,o);(var,p);(while,q);(write,r);4、等于运算符号为一个 = 测试程序:A.C====================== CONST A=10;VAR B,C; PROCEDURE P;VAR D;PROCEDURE Q;VAR X;BEGINREAD(X);D:=X;WHILE XDO CALL P;END;BEGINWRITE(D);CALL Q;END;BEGINCALL P;END.*//*program name:chifufenxi*//*作者:小万 QQ:421404493*//*date:2004.10.11*/#include#include#include#include#include#define N 256//每一行的字符数不能超过256个char buffer[N]; //用作存放一行字符char word[20]; //用作存放经过分析单词char *kword[13]={"begin","call","const","do","end","if","odd","procedure","read","the n","var","while","write"};char ktype[13]={'f','g','h','i','j','k','l','m','n','o','p','q','r'};int len;//记录每一行的长度int count=0;//用来记录行数void write(char *wstr,char wc,FILE *wout)//将分析结果按照规则写入到文件{fputc('(',wout);fputs(wstr,wout);fputc(',',wout);fputc(wc,wout);fputc(')',wout);}int readbuffer(FILE *fp){char ch;len=0;ch=fgetc(fp);while(!feof(fp) && ch!='\n')//读取字符到缓冲区{buffer[len]=ch;ch=fgetc(fp);len++;}len--;//用来控制词法分析时行分析中字母的个数if(feof(fp))//标志文件是否结束return 0;elsereturn 1;}void error(int type){if(type==1)printf("为无效字符,第%d行词法出错,标志符不能以数字开头\n",count); else if(type==2)printf("第%d行词法出错,赋值符应为\:\= \n ",count);else printf("为无效字符,第%d行词法出错\n",count);void check(char *str,FILE *out);//声明函数,此函数用来分类单词void fenxi(char *row,FILE *op)//此函数用来对每一行的单词进行语法分析{//printf("%d\n",count);int k=0;//用作控制临时存放单词的变量str0int i=0;//定义两个变量用作控制每一行是否结束,int ferror=0;//用作出错标志char str0[20];//临时存放单词的变量while(i<=len){k=0;//将k置0strcpy(word,"\0");//将存放单词的变量清空/*去除空格*/if(isspace(row[i]))//去出空格,跳格符,换行符{i++;continue;}/*去出无效字符*/while(!isalpha(row[i])&&!isdigit(row[i])&&i<=len&&!isspace(row[i])&&!(row[i]=='\ 0'||row[i]==':'||row[i]=='>'||row[i]=='<'||row[i]=='+' || row[i]=='-' || row[i]=='*' || row[i]=='/' || row[i]=='(' || row[i]==')' || row[i]==',' || row[i]==';'|| row[i]=='.'|| row[i]=='#' || row[i]=='=')){putchar(row[i]);i++;ferror=1;//设置错误标志符if(ferror==1){error(3);//调用出错处理函数ferror=0;}/*对注释进行处理,假设此语言的注释只能单行注释以双斜杠"//"为注释开始标志*/if(row[i]=='/'){i++;if(row[i]=='/'){i=len+1;//忽略注释符后面的单词continue;}elsei--;}/*判断是否为数字*/if(isdigit(row[i])){while(i<=len&&!isspace(row[i])&&!(row[i]=='\0'||row[i]==':'||row[i]=='>'||row[i] =='<'||row[i]=='+' || row[i]=='-' || row[i]=='*' || row[i]=='/' || row[i]=='(' || row[i]==')' || row[i]==',' || row[i]==';'|| row[i]=='.'|| row[i]=='#' || row[i]=='='))//当不到行尾,是数字或字母当然有可能是无效字符{if(isdigit(row[i]))//是数字则将字符逐个存入临时数组{str0[k]=row[i];i++;k++;// putchar('e');}else //数字中加有字母或无效字符则报错{// putchar('x');ferror=1;break;//已经出错设置标志并退出循环}}if(ferror==1)//检测是否出错{ /*将刚刚的那个单词后面的数字和字母清空,如123abc123或则123$$23等,当出现错误后,需要消除abc123和$$23 以免误作为下一个标志符*/for(int j=0;j putchar(str0[j]);while(i<=len&&!isspace(row[i])&&!(row[i]=='\0'||row[i]==':'||row[i]=='>'||row[i] =='<'||row[i]=='+' || row[i]=='-' || row[i]=='*' || row[i]=='/' || row[i]=='(' || row[i]==')' || row[i]==',' || row[i]==';'|| row[i]=='.'|| row[i]=='#' || row[i]=='=')){putchar(row[i]);i++;}error(1);//putchar('e');//调用出错处理函数ferror=0;//重新设置错误标志位//i--;//strcpy(word,"");}else//未出错照常处理{str0[k]='\0';strcpy(word,str0);i--;//减一是为了使最后取出的那个字符不在被下面的程序判断// str0[0]='\0';}}/*判断是否为标志符和关键字即由字母开头并且不含标点符号用ispunct(int ch)判断标点符号*/if(isalpha(row[i]))//标志符或关键字由字母开头{k=0;while(i<=len&&row[i]!=32&&!(row[i]=='\0'||row[i]==':'||row[i]=='>'||row[i]=='<'| |row[i]=='+' || row[i]=='-' || row[i]=='*' || row[i]=='/' || row[i]=='(' || row[i]==')' || row[i]==',' || row[i]==';'|| row[i]=='.'|| row[i]=='#' || row[i]=='='))//关键字和标志符由数字和字母组成{if(isalpha(row[i])||isdigit(row[i]))//由数字和字母组成{str0[k]=row[i];i++;k++;}else//出错,原因可能是出现了不可识别的字符{ferror=1;break;}}if(ferror){for(int j=0;j putchar(str0[j]);while(i<=len&&!isspace(row[i])&&!(row[i]=='\0'||row[i]==':'||row[i]=='>'||row[i] =='<'||row[i]=='+' || row[i]=='-' || row[i]=='*' || row[i]=='/' || row[i]=='(' || row[i]==')' || row[i]==',' || row[i]==';'|| row[i]=='.'|| row[i]=='#' || row[i]=='=')){putchar(row[i]);//消除整个非法单词i++;}ferror=0;error(3);//i--;}else{str0[k]='\0';strcpy(word,str0);str0[0]='\0';i--;}}/*判断运算符*/if(row[i]=='+' ||row[i]=='-' ||row[i]=='*' || row[i]=='/' || row[i]=='(' || row[i]==')' || row[i]==',' || row[i]==';'||row[i]=='.'||row[i]=='#' || row[i]=='=') {str0[0]=row[i];str0[1]='\0';strcpy(word,str0);str0[0]='\0';}//要先判断单个字符的运算符,以避免诸如>=的运算符后面的=再次被判断if(row[i]==':'){i++;if(row[i]=='='){//word[0]=':';//word[1]='=';//word[2]='\0';strcpy(word,">=");}else{error(2);//出错后调用处理函数i--;}}if(row[i]=='>'){i++;if(row[i]=='='){strcpy(word,">=");}else{strcpy(word,">");i--;}}if(row[i]=='<'){i++;if(row[i]=='='){strcpy(word,"<=");}else{strcpy(word,"<");i--;}}//puts(word);check(word,op);/*调用分类函数,辨别每一个单词的类别要求输入的每一个单词必须符合词法规则*///word[0]='\0';i++;//使指针后移,取出下一个字母}}void check(char *str,FILE *out){if(isdigit(str[0]))/*如果第一个字符是数字那么整个单词都是数字组成的,即为常数*/{write(str,'d',out);//调用写函数将分好类的单词写入文件}if(isalpha(str[0]))/*如果第一个字符是字母,那么这个单词是标志符或关键字*/ {int fyiyong=0;//用作标记这个单词是否已被分类/*以下判别是否是关键字*/for(int ct=0;ct<13;ct++){if(!strcmp(str,kword[ct])){write(str,ktype[ct],out);fyiyong=1;}}/*经过以上判别,可以判别是否是关键字,不是即为标志符*/if(fyiyong!=1){write(str,'e',out);}/*以下对运算符分类*/ if(str[0]=='>'){if(str[1]=='='){write(str,'b',out); }else{write(str,'>',out); }}if(str[0]=='<'){if(str[1]=='='){write(str,'c',out); }else{write(str,'<',out); }}if(!strcmp(str,":=")) {write(str,'a',out); }if(str[0]=='+' || str[0]=='-' || str[0]=='*' || str[0]=='/' || str[0]=='(' || str[0]==')' || str[0]==',' || str[0]==';'|| str[0]=='.'|| str[0]=='#' || str[0]=='=' ){write(str,str[0],out);}}void main(){count=1;char scfilename[20],rsfilename[20];//定义用来存放输入源文件和输出目标文件的名字printf("Please input your source file name:");gets(scfilename);printf("Please input your result file name:");gets(rsfilename);FILE *fp,*op;fp=fopen(scfilename,"r");op=fopen(rsfilename,"w");if(fp)//打开文件成功后调用函数对源文件进行词法分析{while(readbuffer(fp)){fenxi(buffer,op);count++;//行加一}else//while the file not exist{printf("Your souce file not exist!!!\n"); exit(0);}fclose(fp);//close the filesfclose(op);printf("ok!");//output the mark of end getchar();}。

相关文档
最新文档