编译原理及实现-附录C-语法分析程序-代码(包含词法分析代码)

编译原理及实现-附录C-语法分析程序-代码(包含词法分析代码)
编译原理及实现-附录C-语法分析程序-代码(包含词法分析代码)

TESTparse.cpp

#include

#include

#include

#include

intTESTparse();

int program();

intcompound_stat();

int statement();

intexpression_stat();

int expression();

intbool_expr();

intadditive_expr();

int term();

int factor();

intif_stat();

intwhile_stat();

intfor_stat();

intwrite_stat();

intread_stat();

intdeclaration_stat();

intdeclaration_list();

intstatement_list();

intcompound_stat();

//token保存单词符号,token1保存单词值

char token[20] ,token1[40];

//保存词法分析输出文件名

extern char Scanout[300];

//用于指向输入文件的指针

FILE * fp;

//语法分析程序

intTESTparse()

{

intes = 0;

if ((fp = fopen(Scanout,"r")) == NULL)

{

printf("\n 打开文件%s 错误!\n", Scanout);

es = 10;

}

if (es == 0) es = program();

printf("=====语法分析结果! ======== \n");

switch (es)

{

case 0: printf("语法分析成功!\n"); break;

case 10:printf("打开文件%s失败!\n",Scanout); break;

case 1: printf("缺少{! \n");break;

case 2: printf("缺少}! \n"); break;

case 3: printf("缺少标识符!\n"); break;

case 4: printf("少分号! \n"); break;

case 5: printf("缺少(! \n"); break;

case 6: printf("缺少)! \n"); break;

case 7: printf("狹少操作数! \n"); break;

}

fclose(fp);

return(es);

}

//<程序> ::={<声明序列><语句序列>}

//program: := { }

int program()

{

intes = 0;

fscanf(fp, "%s %s\n", token, token1);

printf("%s %s\n", token, token1);

if (strcmp(token, "{")) //判断是否为'{'

{

es = 1;

return(es);

}

fscanf(fp, "%s %s\n", &token, &token1);

printf("%s %s\n", token, token1);

es = declaration_list();

if (es> 0) return(es);

es = statement_list();

if (es> 0) return(es);

if (strcmp(token, "}")) //判断是否为,}'

{

es = 2;

return (es);

}

return(es);

}

//<声明序列>::= <声明序列><声明语句>1<声明语句> //::=

// |e //3tJ^l : :* { } intdeclaration_list()

{

intes=0;

while (strcmp (token, "int")== 0)

{

es=declaration_stat();

if(es>0) return(es);

}

return(es);

}

//<声明语句>::=ID<变量>;

// : : = int ID;

intdeclaration_stat()

{

intes=0;

fscanf(fp, "%s %s\n", &token, &token1);

printf ("%s %s\n",token, token1);

if (strcmp (token, "ID")) return (es*3); //不是标识符

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

if(strcmp(token,"?")) return(es=4);

fscanf (fp, "%s %s\n", &token, &token1);

printf ("%s %s\n",token, token1);

return(es);

}

//<语句序列> ::=<语句序列><语句> |e

// : : = < statement> |e //改成 : :8= {< statement> }

intstatement_list()

{

intes = 0;

while (strcmp(token, "}"))

{

es = statement();

if (es> 0) return (es);

}

return(es);

}

//<语句> :: = | | |丨<复合语句>丨<表达式语句>

//< statement> : : = | |

// | |

int statement()

{

intes = 0;

if (es == 0 &&strcmp(token, "if") == 0) es = if_stat(); //

if (es == 0 &&strcmp(token, "while") == 0) es = while_stat(); //

if (es == 0 &&strcmp(token, "for") == 0) es=for_stat(); //< for 语句>

if (es == 0 &&strcmp(token, "resd") == 0) es = read_stat(); //

if (es == 0 &&strcmp(token, "write") == 0) es = write_stat();//

if (es == 0 &&strcmp(token, "{") == 0) es = compound_stat(); //<复合语句>

if (es == 0 && (strcmp(token, "ID") == 0 || strcmp(token, "NUM") == 0 || strcmp(token, "(") == 0)) es = expression_stat(); //<表达式语句>

return(es);

}

// :: = if (<表达式> ) <语句> 4136<语句>]

// : : = if { ) [else< statement> ]

intif_stat()

{

intes = 0; //if

fscanf(fp, "%s %s\n", &token, &token1);

printf("%s %s\n", token, token1);

if (strcmp(token, " ("))if (es> 0) return (es = 5); //少左括号

fscanf(fp, "%s %s\n", &token, &token1);

printf("%s %s\n", token, token1);

es = expression();

if (es> 0) return(es);

if (strcmp(token, ";"))if (es> 0) return (es = 4); //少分号

fscanf(fp, "%s %s\n", &token, &token1);

printf("%s %s\n", token, token1);

es = expression();

if (es> 0) return (es);

if (strcmp(token, ") "))if (es> 0) return (es = 6); //少右括号

fscanf(fp, "%s %s\n", &token, &token1);

printf("%s %s\n", token, token1);

es = statement(); if (es> 0) return(es);

if (strcmp(token, "else") == 0) //else部分处理

{

fscanf(fp, "%s %s\n", &token, &token1);

printf("%s %s\n", token, token1);

es = statement();

if (es> 0) return (es);

}

return (es);

}

// ::=while (<表达式> ) <语句>

// : : = while () < statement>

intwhile_stat()

{

intes=0;

fscanf(fp,"%s %s\n",&token,&token1);

printf ("%s %s\n",token, token1);

if (strcmp (token," ("))if (es> 0) return (es=5); //少左括号

fscanf (fp, "%s %s\n", &token, &token1) ;

printf("%s %s\n", token, token1);

es=expression();

if(es>0) return(es);

if (strcmp (token, ")"))if (es> 0) return (es= 6); //少右括号

fscanf (fp, "%s %s\n",&token, &token1);

printf("%s %s\n",token,token1);

es=statement();

return(es);

}

//< for语句> :: = for (<表达式> ;<表达式> ;<表达式> ) <语句>

// : :=for ( ; ; ) < statement> intfor_stat()

{

intes = 0;

fscanf(fp, "%s %s\n", &token, &token1);

printf("%s %s\n", token, token1);

if (strcmp(token, " ("))if (es> 0) return (es = 5); //少左括号

fscanf(fp, "%s %s\n", &token, &token1);

printf("%s %s\n", token, token1); es = expression();

if (es> 0) return (es);

if (strcmp(token, ") "))if (es> 0) return (es = 6); //少右括号

fscanf(fp, "%s %s\n", &token, &token1);

printf("%s.%s\n", token, token1);

es = statement();

return(es);

if (strcmp(token, ";"))if (es> 0) return (es = 4); //少分号

fscanf(fp, "%s %s\n", &token, &token1);

printf("%s %s\n", token, token1);

es = expression();

if (es> 0) return (es);

}

//< write_语句> ::=write<表达式>;

// : : = write;;

intwrite_stat()

{

intes=0;

fscanf (fp, "%s %s\n", & token, & token1);

printf ("%s %s\n",token,token1);

es=expression();

if (es>0) return (es);

if (strcmp(token, ";"))if (es> 0) return (es = 4); //少分号

fscanf(fp, "%s %s\n",&token, & token1);

printf("%s %s\n",token,token1);

return(es);

}

// : ^找日化变量>;

// : : = resd ID;

intread_stat()

{

intes=0;

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

if (strcmp (token, "ID"))if (es> 0) return(es=3) ; //例示识符fscanf(fp, "%s %s\n", &token, &token1);

printf("%s %s\n",token,token1);

if(strcmp(token,";"))if (es> 0) return (es=4); //少分号

fscanf (fp,"%s %s\n",&token,&token1);

printf ("%s %s\n",token, token1);

return (es);

}

//<复合语句>::-(<语句序列>}

// : : = { } 一: i>;- ,:; -^ -1 intcompound_stat() //复合语句函数{

intes=0;

fscanf (fp,"%s %s\n",&token,&token1);

printf ("%s %s\n",token, token1);

es= statement_list();

return(es);

}

//<表达式语句>人:= <<表达式>;丨;

// : : = ; | ; intexpression_stat()

{

intes=0;

if (strcmp (token, ";")== 0)

{

fscanf(fp,"%s %s\n",&token,&token1);

printf ("%s %s\n",token,token1) ;

return(es);

}

es=expression();

if(es>0) return(es);

if(es== 0 &&strcmp (token, ";")== 0)

{

fscanf (fp,"%s %s\n", &token, & token1);

printf ("%s %s\n",token, token1);

return(es);

}

else

{

es=4;

return (es); //少分号

}

}

//<表达式> ::"<标识符> = <布尔表达式> |<布尔表达式> // : : = ID== |

int expression()

{

intes=0,filesdd;

char token2[20],token3[40];

if (strcmp(token, "ID") == 0)

{

filesdd = ftell(fp); //记住当前文件位置

fscanf(fp, "%s %sVi", &token2, &token3);

printf("%s %s\n", token2, token3 ) ;

if (strcmp(token2, "=") == 0) // '='

{

fscanf(fp, "%s %s\n", &token, &token1);

printf("%s %s\n", token, token1);

es = bool_expr();

if (es> 0) return(es );

}

else

{

fseek(fp, filesdd, 0);//若非^=’,则文件指针回到'==前的标识符

printf ("%s %s\n" ,token, token1);

es = bool_expr();

if (es> 0) return(es);

}

}

elsees = bool_expr();

return (es) ;

}

//<布尔表达式> :—〈算术表达式> |<算术表达式> (>丨<彳>=丨<=|== f:!=)

//<算术表达式> ^-m.c'.j

// :: =

// | (> |< f>= |< = | == | !*)

intbool_expr()

{

intes=0;

es= additive_expr();

if (es>0) return (es);

if (strcmp (token, ">")== 0 ||strcmp(token,">") ==0 ||strcmp (token, "<")==0 ||strcmp (token, "<=")==0 ||strcmp(token,"==")== 0||strcmp(token,"!= ")== 0)

{

fscanf(fp,"%s %s\n",&token,&token1);

printf ("%s %s\n",token,token1);

es= additive_expr();

if(es>0) return(es);

}

return(es);

}

//<算术表达式> ::= <项> { (+ | -)<项> }

// : : = { (+ | - ) }

intadditive_expr()

{

intes=0;

es=term();

if(es>0) return (es);

while (strcmp(token, "+") == 0 || strcmp(token, "-") == 0)

{

fscanf(fp, "%s %s\n", &token, &token1);

printf("%s %s\n", token, token1);

es = term();

if (es> 0) return (es);

}

return(es);

}

// <项> ::48 <因子> | ( * | / ) <因子> )>

// : :* { ( * ( /)< factor> }

int term()

{

intes=0;

es= factor();

if (es>0) return (es);

while(strcmp(token,"*")==0||strcmp(token,"/")== 0)

{

fscanf(fp,"%s %s\n",&token,&token1);

printf ("%s %s\n",token,token1);

es= factor();

if (es>0) return (es);

}

return(es);

}

//<因子>::(<表达式>>丨<标识符> |<无符号整数>

//: := ()丨ID|NUM

int factor()

{

intes=0;

if (strcmp (token, " (")== 0)

{

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=expression();

if(es>0) return (es);

if (strcmp (token, ") ")) return (es=6); //少右括号

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1) ;

}

else

{

if (strcmp(token, "ID") == 0 || strcmp(token, "NUM") == 0)

{

fscanf(fp, "%s %s\n", &token, &token1);

printf("%s %s\n", token, token1);

return(es);

}

else

{

es = 7; //缺少操作数

return(es);

}

}

return(es);

}

TESTscan.cpp

#include

#include

#include

#define keywordSum 8

char *keyword[keywordSum]={"if","else","for","while","do","int","read","write"};//添加的保留字do;

charsingleword[50]="+ - * () {} ; , : ";

chardoubleword[10]=">< = ! ";

chardoublewordhe[10]="&&";

char doublewordhuo[10]="||";//添加双分界符

chardoublewordjia[10]="++";

extern char Scanin[300],Scanout[300];

extern FILE * fin,*fout;

intTESTscan()

{

charch,token[40];

intes=0,j,n;

printf ("请输入源程序文件名(包括路径):");

scanf ("%s",Scanin);

printf ("请输入词法分析输出文件名(包括路径):");

scanf ("%s",Scanout);

if ((fin=fopen(Scanin,"r"))==NULL)

{

printf("\n打开词法分析输入文件出错!\n");

return(1);

}

if((fout=fopen(Scanout,"w"))==NULL)

{

printf("\n创建词法分析输出文件出错!\n");

return(2);

}

ch=getc(fin);

while(ch!=EOF)

{

while (ch==' '|| ch=='\n'|| ch=='\t')ch=getc(fin);

if(isalpha(ch))

{

token[0]=ch;j=1;

ch=getc(fin);

while(isalnum(ch))

{

token[j++]=ch;

ch=getc(fin);

}

token[j]='\0';

n=0;

while ((n

if(n>=keywordSum)

fprintf(fout,"%s\t%s\n","ID",token);

else

fprintf(fout,"%s\t%s\n",token,token);

}

else if (isdigit(ch))

{

token[0]=ch;

j=1;

ch=getc(fin);

while (isdigit(ch))

{

token[j++]=ch;

ch=getc(fin);

}

token[j]='\0';

fprintf(fout,"%s\t%s\n","NUM",token); }

else if (strchr(doubleword,ch)>0)

{

token[0]=ch;

ch=getc(fin);

token[1]='\0';

fprintf(fout,"%s\t%s\n",token,token); }

else if(strchr(doublewordhe,ch)>0)

{

token[0]=ch;

ch=getc(fin);

if(ch=='&')

{

token[1]=ch;

token[2]='\0';

ch=getc(fin);

}

else

token[1]='\0';

fprintf(fout,"%s\t%s\n",token,token); }//所加代码;

else if(strchr(doublewordhuo,ch)>0)

{

token[0]=ch;

ch=getc(fin);

if(ch=='|')

{

token[1]=ch;

token[2]='\0';

ch=getc(fin);

}

else

token[1]='\0';

fprintf(fout,"%s\t%s\n",token,token); }//所加代码;

else if(strchr(doublewordjia,ch)>0)

{

token[0]=ch;

ch=getc(fin);

if(ch=='+')

{

token[1]=ch;

token[2]='\0';

ch=getc(fin);

}

else

token[1]='\0';

fprintf(fout,"%s\t%s\n",token,token);

}//所加代码;

else if (strchr(singleword,ch)>0)

{

token[0]=ch;

token[1]='\0';

ch=getc(fin);

fprintf(fout,"%s\t%s\n",token,token);

}

else if (ch=='/')

{

ch=getc(fin);

if (ch=='*')

{

char ch1;

ch1=getc(fin);

do

{

ch=ch1;ch1=getc(fin);

}

while ((ch!='*'||ch1!='/')&&ch1!=EOF);

ch=getc(fin);

}

else

{

token[0]=ch;token[1]='\0';

fprintf(fout,"%s\t%s\n",token,token);

}

}

else

{

token[0]=ch;token[1]='\0';

ch=getc(fin);

es=3;

fprintf(fout,"%s\t%s]\n","ERROR",token); }

}

fclose(fin);

fclose(fout);

return(es);

}

main.cpp

#include

#include

externintTESTscan();

externintTESTparse();

char Scanin[300],Scanout[300] ; //用于接收输入输出文件名FILE * fin, * fout; //用于指向输入输出文件的指针

void main ()

{

intes=0;

es=TESTscan(); //调词法分析

if (es>0) printf ("词法分析有错,编译停止!") ;

else printf ("词法分析成功!\n");

if (es == 0)

{

es=TESTparse(); //调语法分析

if(es==0)printf("语法分析成功!\n");

else printf ("语法分析错误!\n");

}

}

编译原理课程设计-词法语法分析器

编译原理课程设计Course Design of Compiling (课程代码3273526) 半期题目:词法和语法分析器 实验学期:大三第二学期 学生班级:2014级软件四班 学生学号:2014112218 学生姓名:何华均 任课教师:丁光耀 信息科学与技术学院 2017.6

课程设计1-C语言词法分析器 1.题目 C语言词法分析 2.内容 选一个能正常运行的c语言程序,以该程序出现的字符作为单词符号集,不用处理c语言的所有单词符号。 将解析到的单词符号对应的二元组输出到文件中保存 可以将扫描缓冲区与输入缓冲区合成一个缓冲区,一次性输入源程序后就可以进行预处理了 3.设计目的 掌握词法分析算法,设计、编制并调试一个词法分析程序,加深对词法分析原理的理解 4.设计环境(电脑语言环境) 语言环境:C语言 CPU:i7HQ6700 内存:8G 5.概要设计(单词符号表,状态转换图) 5.1词法分析器的结构 词法分析程序的功能:

输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 词法分析程序可以单独为一个程序;也可以作为整个编译程序的一个子程序,当需要一个单词时,就调用此法分析子程序返回一个单词. 为便于程序实现,假设每个单词间都有界符或运算符或空格隔开,并引入下面的全局变量及子程序: 1) ch 存放最新读进的源程序字符 2) strToken 存放构成单词符号的字符串 3) Buffer 字符缓冲区 4)struct keyType 存放保留字的符号和种别 5.2待分析的简单词法 (1)保留字 break、case、char、const、int、do、while… (2)运算符和界符 = 、+、-、* 、/、%、,、;、(、)、?、# 5.3各种单词符号对应的种别码

编译原理语法分析实验报告

编译原理语法分析实验报告 - 班级:XXX 学号:XXX 姓名:XXX 年月日 1、摘要: 用递归子程序法实现对pascal的子集程序设计语言的分析程序 2、实验目的: 通过完成语法分析程序,了解语法分析的过程和作用 3、任务概述 实验要求:对源程序的内码流进行分析,如为文法定义的句子输出”是”否则输出”否”,根据需要处理说明语句填写写相应的符号表供以后代码生成时使用 4、实验依据的原理 递归子程序法是一种自顶向下的语法分析方法,它要求文法是LL(1)文法。通过对文法中每个非终结符编写一个递归过程,每个过程的功能是识别由该非终结符推出的串,当某非终结符的产生式有多个候选式时,程序能够按LL(1)形式唯一地确定选择某个候选式进行推导,最终识别输入串是否与文法匹配。 递归子程序法的缺点是:对文法要求高,必须满足LL(1)文法,当然在某些语言中个别产生式的推导当不满足LL(1)而满足LL(2)时,也可以采用多向前扫描一个符号的办法;它的另一个缺点是由于递归调用多,所以速度慢占用空间多,尽管这样,它还是许多高级语言,例如PASCAL,C等编译系统常常采用的语法分析方法。

为适合递归子程序法,对实验一词法分析中的文法改写成无左递归和无左共因子的,,,如下: <程序>?<程序首部><分程序>。 <程序首部>?PROGRAM标识符; <分程序>?<常量说明部分><变量说明部分><过程说明部分> <复合语句> <常量说明部分>?CONST<常量定义><常量定义后缀>;|ε <常量定义>?标识符=无符号整数 <常量定义后缀>?,<常量定义><常量定义后缀> |ε <变量说明部分>?VAR<变量定义><变量定义后缀> |ε <变量定义>?标识符<标识符后缀>:<类型>; <标识符后缀>?,标识符<标识符后缀> |ε <变量定义后缀>?<变量定义><变量定义后缀> |ε <类型>?INTEGER | LONG <过程说明部分>?<过程首部><分程序>;<过程说明部分后缀>|ε <过程首部>?PROCEDURE标识符<参数部分>; <参数部分>?(标识符: <类型>)|ε <过程说明部分后缀>?<过程首部><分程序>;<过程说明部分后缀>|ε <语句>?<赋值或调用语句>|<条件语句>|<当型循环语句>|<读语句> |<写语句>|<复合语句>|ε <赋值或调用语句>?标识符<后缀> <后缀>?:=<表达式>|(<表达式>)|ε <条件语句>?IF<条件>THEN<语句> <当型循环语句>?WHILE<条件>DO <语句> <读语句>?READ(标识符<标识符后缀>)

编译原理词法分析器语法分析器实验报告

编译技术 班级网络0802 学号3080610052姓名叶晨舟 指导老师朱玉全2011年 7 月 4 日

一、目的 编译技术是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。 二、任务及要求 基本要求: 1.词法分析器产生下述小语言的单词序列 这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表: 单词符号种别编码助记符内码值 DIM IF DO STOP END 标识符 常数(整)= + * ** , ( )1 2 3 4 5 6 7 8 9 10 11 12 13 14 $DIM $IF $DO $STOP $END $ID $INT $ASSIGN $PLUS $STAR $POWER $COMMA $LPAR $RPAR - - - - - - 内部字符串 标准二进形式 - - - - - - 对于这个小语言,有几点重要的限制: 首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。例如,下面的写法是绝对禁止的: IF(5)=x 其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。也就是说,对于关键字不专设对应的转换图。但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。 再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。例如,一个条件语句应写为

词法分析程序设计与实现

` 实验一词法分析程序设计与实现 一、实验目的及容 调试并完成一个词法分析程序,加深对词法分析原理的理解。 二、实验原理(状态转换图) 1、C语言子集 (1)关键字: begin if then while do end 所有关键字都是小写。 (2)运算符和界符: := + – * / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:ID=letter(letter| digit)* NUM=digit digit * (4)空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。 2、各种单词符号对应的种别码 文档Word

` 3、词法分析程序的功能 输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 二、软件平台及工具 PC机以及VISUAL C++6.0软件。 三、实验方法、步骤(或:程序代码或操作过程)(1)程序代码: #include #include #include char prog[80],token[8]; char ch; int syn,p,m=0,n,row,sum=0; char *rwtab[6]={egin,if,hen,while,do,end}; void scaner() { for(n=0;n<8;n++) token[n]=NULL; ch=prog[p++]; while(ch==' ') { ch=prog[p]; p++; } if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) 文档Word ` {

编译原理-编写递归下降语法分析器

学号107 成绩 编译原理上机报告 名称:编写递归下降语法分析器 学院:信息与控制工程学院 专业:计算机科学与技术 班级:计算机1401班 姓名:叶达成 2016年10月31日

一、上机目的 通过设计、编制、调试一个递归下降语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,掌握常用的语法分析方法。通过本实验,应达到以下目标: 1、掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。 2、掌握词法分析的实现方法。 3、上机调试编出的词法分析程序。 二、基本原理和上机步骤 递归下降分析程序实现思想简单易懂。程序结构和语法产生式有直接的对应关系。因为每个过程表示一个非终结符号的处理,添加语义加工工作比较方便。 递归下降分析程序的实现思想是:识别程序由一组子程序组成。每个子程序对应于一个非终结符号。 每一个子程序的功能是:选择正确的右部,扫描完相应的字。在右部中有非终结符号时,调用该非终结符号对应的子程序来完成。 自上向下分析过程中,如果带回溯,则分析过程是穷举所有可能的推导,看是否能推导出待检查的符号串。分析速度慢。而无回溯的自上向下分析技术,当选择某非终结符的产生时,可根据输入串的当前符号以及各产生式右部首符号而进行,效率高,且不易出错。 无回溯的自上向下分析技术可用的先决条件是:无左递归和无回溯。 无左递归:既没有直接左递归,也没有间接左递归。 无回溯:对于任一非终结符号U的产生式右部x1|x2|…|x n,其对应的字的首终结符号两两不相交。 如果一个文法不含回路(形如P?+ P的推导),也不含以ε为右部的产生式,那么可以通过执行消除文法左递归的算法消除文法的一切左递归(改写后的文法可能含有以ε为右部的产生式)。 三、上机结果 测试数据: (1)输入一以#结束的符号串(包括+—*/()i#):在此位置输入符号串例如:i+i*i# (2)输出结果:i+i*i#为合法符号串 (3)输入一符号串如i+i*#,要求输出为“非法的符号串”。 程序清单: #include #include char str[50]; int index=0; void E(); //E->TX; void X(); //X->+TX | e void T(); //T->FY void Y(); //Y->*FY | e void F(); //F->(E) | i int main() /*递归分析*/ { int len; int m;

编译原理词法分析和语法分析报告 代码(C语言版)

词法分析 三、词法分析程序的算法思想: 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 3.1 主程序示意图: 扫描子程序主要部分流程图 其他

词法分析程序的C语言程序源代码: // 词法分析函数: void scan() // 数据传递: 形参fp接收指向文本文件头的文件指针; // 全局变量buffer与line对应保存源文件字符及其行号,char_num保存字符总数。 void scan() { char ch; int flag,j=0,i=-1; while(!feof(fp1)) { ch=fgetc(fp1); flag=judge(ch); printf("%c",ch);//显示打开的文件 if(flag==1||flag==2||flag==3) {i++;buffer[i]=ch;line[i]=row;} else if(flag==4) {i++;buffer[i]='?';line[i]=row;} else if(flag==5) {i++;buffer[i]='~';row++;} else if(flag==7) continue; else cout<<"\n请注意,第"<

编译原理词法分析和语法分析报告+代码(C语言版)

词法分析 一、实验目的 设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求 2.1 待分析的简单的词法 (1)关键字: begin if then while do end 所有的关键字都是小写。 (2)运算符和界符 : = + - * / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义: ID = letter (letter | digit)* NUM = digit digit* (4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。 2.2 各种单词符号对应的种别码: 输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列: (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)…… 三、词法分析程序的算法思想: 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

3.1 主程序示意图: 主程序示意图如图3-1所示。其中初始包括以下两个方面: ⑴关键字表的初值。 关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下: Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,}; 图3-1 (2)程序中需要用到的主要变量为syn,token和sum 3.2 扫描子程序的算法思想: 首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。

编译原理实验 (词法语法分析报告 附源代码

编译原理实验报告 ******************************************************************************* ******************************************************************************* PL0语言功能简单、结构清晰、可读性强,而又具备了一般高级程序设计语言的必须部分,因而PL0语言的编译程序能充分体现一个高级语言编译程序实现的基本方法和技术。PL/0语言文法的EBNF表示如下: <程序>::=<分程序>. <分程序> ::=[<常量说明>][<变量说明>][<过程说明>]<语句> <常量说明> ::=CONST<常量定义>{,<常量定义>}; <常量定义> ::=<标识符>=<无符号整数> <无符号整数> ::= <数字>{<数字>} <变量说明> ::=VAR <标识符>{, <标识符>}; <标识符> ::=<字母>{<字母>|<数字>} <过程说明> ::=<过程首部><分程序>{; <过程说明> }; <过程首部> ::=PROCEDURE <标识符>; <语句> ::=<赋值语句>|<条件语句>|<当循环语句>|<过程调用语句> |<复合语句>|<读语句><写语句>|<空> <赋值语句> ::=<标识符>:=<表达式> <复合语句> ::=BEGIN <语句> {;<语句> }END <条件语句> ::= <表达式> <关系运算符> <表达式> |ODD<表达式> <表达式> ::= [+|-]<项>{<加法运算符> <项>} <项> ::= <因子>{<乘法运算符> <因子>} <因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’ <加法运算符> ::= +|- <乘法运算符> ::= *|/ <关系运算符> ::= =|#|<|<=|>|>= <条件语句> ::= IF <条件> THEN <语句> <过程调用语句> ::= CALL 标识符 <当循环语句> ::= WHILE <条件> DO <语句> <读语句> ::= READ‘(’<标识符>{,<标识符>}‘)’ <写语句> ::= WRITE‘(’<表达式>{,<表达式>}‘)’ <字母> ::= a|b|…|X|Y|Z <数字> ::= 0|1|…|8|9 【预处理】 对于一个pl0文法首先应该进行一定的预处理,提取左公因式,消除左递归(直接或间接),接着就可以根据所得的文法进行编写代码。 【实验一】词法分析 【实验目的】给出PL/0文法规,要求编写PL/0语言的词法分析程序。 【实验容】已给PL/0语言文法,输出单词(关键字、专用符号以及其它标记)。

实验1-3 《编译原理》词法分析程序设计方案

实验1-3 《编译原理》S语言词法分析程序设计方案 一、实验目的 了解词法分析程序的两种设计方法之一:根据状态转换图直接编程的方式; 二、实验内容 1.根据状态转换图直接编程 编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。在此,词法分析程序作为单独的一遍,如下图所示。 具体任务有: (1)组织源程序的输入 (2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件 (3)删除注释、空格和无用符号 (4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。将错误信息输出到屏幕上。 (5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。 标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址 注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。 常量表结构:常量名,常量值 三、实验要求 1.能对任何S语言源程序进行分析 在运行词法分析程序时,应该用问答形式输入要被分析的S源语言程序的文件名,然后对该程序完成词法分析任务。 2.能检查并处理某些词法分析错误 词法分析程序能给出的错误信息包括:总的出错个数,每个错误所在的行号,错误的编号及错误信息。 本实验要求处理以下两种错误(编号分别为1,2): 1:非法字符:单词表中不存在的字符处理为非法字符,处理方式是删除该字符,给出错误信息,“某某字符非法”。 2:源程序文件结束而注释未结束。注释格式为:/* …… */ 四、保留字和特殊符号表

编译原理课程设计(词法分析,语法分析,语义分析,代码生成)

编译原理课程设计(词法分析,语法分析,语义分析,代码 生成) #include #include #include #include #include #include using namespace std; /************************************************/ struct token// token { int code;// int num;// token *next; }; token *token_head,*token_tail;//token struct str// string { int num;// string word;// str *next; }; str *string_head,*string_tail;//string struct ivan// {

char left;// string right;// int len;// }; ivan css[20];// 20 struct pank// action { char sr;// int state;// }; pank action[46][18];//action int go_to[46][11];// go_to struct ike// { ike *pre; int num;// int word;// ike *next; }; ike *stack_head,*stack_tail;// struct L// { int k; string op;// string op1;// string op2;// string result;// L *next;// L *Ltrue;//true L *Lfalse;//false };

编译原理课程设计-词法分析器(附含源代码)

编译原理-词法分析器的设计 一.设计说明及设计要求 一般来说,编译程序的整个过程可以划分为五个阶段:词法分析、语法分析、中间代码生成、优化和目标代码生成。本课程设计即为词法分析阶段。词法分析阶段是编译过程的第一个阶段。这个阶段的任务是从左到右一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号)。如保留字(关键字或基本字)、标志符、常数、算符和界符等等。 二.设计中相关关键字说明 1.基本字:也称关键字,如C语言中的 if , else , while , do ,for,case,break, return 等。 2.标志符:用来表示各种名字,如常量名、变量名和过程名等。 3.常数:各种类型的常数,如12,6.88,和“ABC” 等。 4.运算符:如 + ,- , * , / ,%, < , > ,<= , >= 等。5.界符,如逗点,冒号,分号,括号,# ,〈〈,〉〉等。 三、程序分析 词法分析是编译的第一个阶段,它的主要任务是从左到右逐个字符地对源 程序进行 扫描,产生一个个单词序列,用以语法分析。词法分析工作可以是独立的一遍,把字符流的源程序变为单词序列,输出在一个中间文件上,这个文件做为语法分析程序的输入而继续编译过程。然而,更一般的情况,常将

词法分析程序设计成一个子程序,每当语法分析程序需要一个单词时,则 调用该子程序。词法分析程序每得到一次调用,便从源程序文件中读入一 些字符,直到识别出一个单词,或说直到下一个单词的第一个字符为止。 四、模块设计 下面是程序的流程图 五、程序介绍 在程序当前目录里建立一个文本文档,取名为infile.txt,所有需要分析的程序都写在此文本文档里,程序的结尾必须以“@”标志符结束。程序结果输出在同一个目录下,文件名为outfile.txt,此文件为自动生成。本程序所输出的单词符号采用以下二元式表示:(单词种别,单词自身的值)如程序输出结果(57,"#")(33,"include")(52,"<")(33,"iostream") 等。 程序的功能:(1)能识别C语言中所有关键字(共32个)(单词种别分别为1 — 32 ,详情见程序代码相关部分,下同) (2)能识别C语言中自定义的标示符(单词种别为 33) (3)能识别C语言中的常数(单词种别为0) (4)能识别C语言中几乎所有运算符(单词种别分别为41 — 54) (5)能识别C语言中绝大多数界符(单词种别分别为 55 — 66)六、运行结果 输入文件infile.txt 运行结果(输出文件 outfile.txt)

编译原理-语法分析-算符优先文法分析器

编译原理实验报告 实验名称:编写语法分析分析器实验类型: 指导教师: 专业班级: 学号: 电子邮件: 实验地点: 实验成绩:

一、实验目的 通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。 1、选择最有代表性的语法分析方法,如LL(1) 语法分析程序、算符优先分析程序和LR分析分析程序,至少选一题。 2、选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。 二、实验过程 编写算符优先分析器。要求: (a)根据算符优先分析算法,编写一个分析对象的语法分析程序。读者可根据自己的能力选择以下三项(由易到难)之一作为分析算法中的输入: Ⅰ:通过构造算符优先关系表,设计编制并调试一个算法优先分析程序Ⅱ:输入FIRSTVT,LASTVT集合,由程序自动生成该文法的算符优先关系矩阵。 Ⅲ:输入已知文法,由程序自动生成该文法的算符优先关系矩阵。(b)程序具有通用性,即所编制的语法分析程序能够使用于不同文法以及各种输入单词串,并能判断该文法是否为算符文法和算符优先文法。 (c)有运行实例。对于输入的一个文法和一个单词串,所编制的语法分析程序应能正确地判断,此单词串是否为该文法的句子,并要求输出分析过程。 三、实验结果 算符优先分析器: 测试数据:E->E+T|T T->T*F|F F->(E)|i 实验结果:(输入串为i+i*i+i)

四、讨论与分析 自下而上分析技术-算符优先分析法: 算符文法:一个上下无关文法G,如果没有且没有P→..QR...(P ,Q ,R属于非终结符),则G是一个算符文法。 FIRSTVT集构造 1、若有产生式P →a...或P →Qa...,则a∈FIRSTVT(P)。 2、若有产生式P→...,则FIRSTVT(R)包含在FIRSTVT(P)中。由优先性低于的定义和firstVT集合的定义可以得出:若存在某个产生式:…P…,则对所有:b∈firstVT(P)都有:a≦b。 构造优先关系表: 1、如果每个非终结符的FIRSTVT和LASTVT集均已知,则可构造优先关系表。 2、若产生式右部有...aP...的形式,则对于每个b∈FIRSTVT(P)都有

编译原理实验词法分析语法分析

本代码只供学习参考: 词法分析源代码: #include #include #include using namespace std; string key[8]={"do","end","for","if","printf","scanf","then","while"}; string optr[4]={"+","-","*","/"}; string separator[6]={",",";","{","}","(",")"}; char ch; //判断是否为保留字 bool IsKey(string ss) { int i; for(i=0;i<8;i++) if(!strcmp(key[i].c_str(),ss.c_str())) return true; return false; } //字母判断函数 bool IsLetter(char c) { if(((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z'))) return true; return false; } //数字判断函数 bool IsDigit(char c) { if(c>='0'&&c<='9') return true; return false; } //运算符判断函数 bool IsOptr(string ss) { int i; for(i=0;i<4;i++) if(!strcmp(optr[i].c_str(),ss.c_str())) return true ; return false; } //分界符判断函数 bool IsSeparator(string ss) { int i; for(i=0;i<6;i++) if(!strcmp(separator[i].c_str(),ss.c_str()))

编译器的词法分析器

一.实验目的 ●了解编译器的词法分析器的作用。其作用是源程序转化为便于编译程序其余部分进行处 理的内部格式。 ●了解词法分析器的任务。识别出源程序中的各个基本语法单位;删除无用的空白字符, 回车以及其他与输入介质相关的非实质性的字符,以及注释等。 一.实验说明 ●词法分析程序:词法分析程序完成的是编译第一阶段的工作。词法分析工作可以是独立 的一遍,把字符流的源程序变为单词序列,输出在一个中间文件上,这个文件做为语法分析程序的输入而继续编译过程。然而,更一般的情况,是将词法分析程序设计成一个子程序,每当语法分析程序需要一个单词时,则调用该子程序。词法分析程序每得到一次调用,便从源程序文件中读入一些字符,直到识别出一个单词,或说直到下一单词的第一个字符为止。 ●词法分析程序的主要功能是从字符流的源程序中识别单词,它要从左至右逐个字符地扫 描源程序,因此它还可完成其它一些任务。比如,滤掉源程序中的注释和空白(由空格,制表或回车换行字符引起的空白);又比如,为了使编译程序能将发现的错误信息与源程序的出错位置联系起来,词法分析程序负责记录新读入的字符行的行号,以便行号与出错信息相联;再有,在支持宏处理功能的源语言中,可以由词法分析程序完成其预处理等等。 ●以下是五种单词符号: - 保留字,关键字 - 标识符 - 常数(量) - 运算符 - 界符 ●词法分析程序所输出的单词符号常常采用以下二元式表示:(单词种别,单词自身的值)。 单词的种别是语法分析需要的信息,而单词自身的值则是编译其它阶段需要的信息。比如在PASCAL的语句const i=25, yes=1;中的单词25和1的种别都是常数,常数的值25和1对于代码生成来说,是必不可少的。有时,对某些单词来说,不仅仅需要它的值,还需要其它一些信息以便编译的进行。比如,对于标识符来说,还需要记载它的类别、层次还有其它属性,如果这些属性统统收集在符号表中,那么可以将单词的二元式表示设计成如下形式(标识符,指向该标识符所在符号表中位置的指针),如上述语句中

编译原理词法分析器

一、实验目的 了解词法分析程序的两种设计方法:1.根据状态转换图直接编程的方式;2.利用DFA 编写通用的词法分析程序。 二、实验内容及要求 1.根据状态转换图直接编程 编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。在此,词法分析程序作为单独的一遍,如下图所示。 具体任务有: (1)组织源程序的输入 (2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件 (3)删除注释、空格和无用符号 (4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。将错误信息输出到屏幕上。 (5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。 标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址 注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。 常量表结构:常量名,常量值 2.编写DFA模拟程序 算法如下: DFA(S=S0,MOVE[][],F[],ALPHABET[]) /*S为状态,初值为DFA的初态,MOVE[][]为状态转换矩阵,F[] 为终态集,ALPHABET[] 为字母表,其中的字母顺序与MOVE[][] 中列标题的字母顺序一致。*/ { Char Wordbuffer[10]=“”//单词缓冲区置空 Nextchar=getchar();//读 i=0; while(nextchar!=NULL)//NULL代表此类单词 { if (nextcha r!∈ALPHABET[]){ERROR(“非法字符”),return(“非法字符”);} S=MOVE[S][nextchar] //下一状态 if(S=NULL)return(“不接受”);//下一状态为空,不能识别,单词错误 wordbuffer[i]=nextchar ;//保存单词符号 i++; nextchar=getchar(); } Wordbuffer[i]=‘\0’;

编译原理 语法分析器 (java完美运行版)

实验二语法分析器 一、实验目的 通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。有利于提高学生的专业素质,为培养适应社会多方面需要的能力。 二、实验内容 ◆根据某一文法编制调试LL (1 )分析程序,以便对任意输入的符号串 进行分析。 ◆构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分 析程序。 ◆分析法的功能是利用LL(1)控制程序根据显示栈栈顶内容、向前看符号 以及LL(1)分析表,对输入符号串自上而下的分析过程。 三、LL(1)分析法实验设计思想及算法 ◆模块结构: (1)定义部分:定义常量、变量、数据结构。 (2)初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等); (3)控制部分:从键盘输入一个表达式符号串; (4)利用LL(1)分析算法进行表达式处理:根据LL(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。

四、实验要求 1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。 2、如果遇到错误的表达式,应输出错误提示信息。 3、对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG (2)G->+TG|—TG (3)G->ε (4)T->FS (5)S->*FS|/FS (6)S->ε (7)F->(E) (8)F->i 输出的格式如下:

五、实验源程序 LL1.java import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.sql.*; import java.util.Vector; public class LL1 extends JFrame implements ActionListener { /** * */ private static final long serialVersionUID = 1L; JTextField tf1; JTextField tf2; JLabel l; JButton b0; JPanel p1,p2,p3; JTextArea t1,t2,t3; JButton b1,b2,b3;

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

实验一词法分析程序的设计与实现 一、实验内容 【实验目的和要求】 设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解。 【实验内容】 通过对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)界符:如“,”、“;”、“(”、“)”、“.”等。 注意事项 ●空格的作用仅仅是将一个个单词分割开来,源程序中的空格不具备别的语法意义,在语法分析及其后续阶段都没有任何作用,因此,词法分析的另一个工作是过滤空格。 ●注释对整个源程序的编译也没有任何语法意义,只是为了便于阅读和交流,因此,有的编译程序的词法分析程序也负责过滤注释。 ●输出的单词符号采用[单词类别,单词自身值]的二元组形式来表示。 ●为了使扫描程序尽可能的高效,在进行词法分析程序的设计和实现时还需十分注意扫描程序结构的实际细节问题。 ●用于间隔单词的空格和我们通常所说的键盘上的空格是不同的,这里的空格指的是所有能引起一个单词结束的字符,它们包括空格、制表或回车换行符。 ●a*(b+c)这样的没有空格间隔的情况时要正确地识别出所有的单词 ●123ab这样的字符串时,一般字符串的首字符必须为字母,不要将123识别为数字,将ab识别为标识符 转换图说明

编译原理词法分析实验报告

词法分析器实验报告 一、实验目的 选择一种编程语言实现简单的词法分析程序,设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求 2、1 待分析的简单的词法 (1)关键字: begin if then while do end 所有的关键字都就是小写。 (2)运算符与界符 : = + - * / < <= <> > >= = ; ( ) # (3)其她单词就是标识符(ID)与整型常数(SUM),通过以下正规式定义: ID = letter (letter | digit)* NUM = digit digit* (4)空格有空白、制表符与换行符组成。空格一般用来分隔ID、SUM、运算符、界符与关键字,词法分析阶段通常被忽略。 2、2 各种单词符号对应的种别码: 表2、1 各种单词符号对应的种别码 2、3 词法分析程序的功能: 输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列: (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)…… 三、词法分析程序的算法思想: 算法的基本任务就是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想就是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 3、1 主程序示意图:

主程序示意图如图3-1所示。其中初始包括以下两个方面: ⑴ 关键字表的初值。 关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下: Char *rwtab[6] = {“begin ”, “if ”, “then ”, “while ”, “do ”, “end ”,}; (2)3、2 扫描子程序的算法思想: 首先设置3个变量:①token 用来存放构成单词符号的字符串;②sum 用来整型单词;③syn 用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。

昆明理工大学 编译原理 实验二 语法分析器

昆明理工大学信息工程与自动化学院学生实验报告 (2011 —2012 学年第 1 学期) 课程名称:编译原理开课实验室: 445 2011年 12 月 19日年级、专业、 班 计科093 学号200910405310 姓名孙浩川成绩 实验项目名称语法分析器指导教师严馨 教 师评语 该同学是否了解实验原理: A.了解□ B.基本了解□ C.不了解□ 该同学的实验能力: A.强□ B.中等□ C.差□ 该同学的实验是否达到要求: A.达到□ B.基本达到□ C.未达到□ 实验报告是否规范: A.规范□ B.基本规范□ C.不规范□ 实验过程是否详细记录: A.详细□ B.一般□ C.没有□ 教师签名: 年月日 一、实验目的及内容 实验目的:编制一个语法分析程序,实现对词法分析程序所提供的单词序列进行语法检 查和结构分析。 实验内容:在上机(一)词法分析的基础上,采用递归子程序法或其他适合的语法分析方法,实现其语法分析程序。要求编译后能检查出语法错误。 已知待分析的C语言子集的语法,用EBNF表示如下: <程序>→main()<语句块> <语句块> →‘{’<语句串>‘}’ <语句串> → <语句> {; <语句> }; <语句> → <赋值语句> |<条件语句>|<循环语句> <赋值语句>→ID=<表达式>

<条件语句>→if‘(‘条件’)’<语句块> <循环语句>→while’(‘<条件>’)‘<语句块> <条件> → <表达式><关系运算符> <表达式> <表达式> →<项>{+<项>|-<项>} <项> → <因子> {* <因子> |/ <因子>} <因子> →ID|NUM| ‘(’<表达式>‘)’ <关系运算符> →<|<=|>|>=|==|!= 二、实验原理及基本技术路线图(方框原理图或程序流程图)

编译原理词法分析器语法分析课程设计报告书

《编译原理》 课程设计 院系信息科学与技术学院 专业软件工程 年级 2011级 学号 20112723 姓名林苾湲 西南交通大学信息科学与技术学院 2013年 12月

目录 课程设计1 词法分析器 (2) 1.1 设计题目 (2) 1.2 设计容 (2) 1.3 设计目的 (2) 1.4 设计环境 (2) 1.5 需求分析 (2) 1.6 概要设计 (2) 1.7 详细设计 (4) 1.8 编程调试 (5) 1.9 测试 (11) 1.10 结束语 (13) 课程设计2 赋值语句的解释程序设计 (14) 2.1 设计题目 (14) 2.2 设计容 (14) 2.3 设计目的 (14) 2.4 设计环境 (14) 2.5 需求分析 (15) 2.6 概要设计 (16) 2.7 详细设计 (16) 2.8 编程调试 (24) 2.9 测试 (24) 2.10 结束语 (25)

课程设计一词法分析器设计 一、设计题目 手工设计c语言的词法分析器(可以是c语言的子集)。 二、设计容 处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。 三、设计目的 了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。 四、设计环境 该课程设计包括的硬件和软件条件如下: 4.1.硬件 (1)Intel Core Duo CPU P8700 (2)存4G 4.2.软件 (1)Window 7 32位操作系统 (2)Microsoft Visual Studio c#开发平台 4.3.编程语言 C#语言 五、需求分析 5.1.源程序的预处理:源程序中,存在许多编辑用的符号,他们对程序逻辑功能无任何影响。例如:回车,换行,多余空白符,注释行等。在词法分析之前,首先要先剔除掉这些符号,使得词法分析更为简单。 5.2.单词符号的识别并判断单词的合法性:将每个单词符号进行不同类别的划分。单词符号可以划分成5中。 (1)标识符:用户自己定义的名字,常量名,变量名和过程名。 (2)常数:各种类型的常数。 (3) 保留字(关键字):如if、else、while、int、float等。 (4) 运算符:如+、-、*、<、>、=等。 (5)界符:如逗号、分号、括号等。 5.3.将所有合法的单词符号转化为便于计算机处理的二元组形式:(单词分类号,单词自身值);以图形化界面显示出来。 5.4.可选择性地将结果保存到文件中。 六、概要设计 6.1.数据类型 6.1.1.单词的分类:本词法分析器演示的是C语言的一个子集,故字符集如下:

相关文档
最新文档