编译原理第三版附带的实验源码
编译原理何炎祥第三版pdf

编译原理何炎祥第三版pdf《编译原理》是计算机科学与技术领域重要的教材之一。
本文将为大家详细介绍何炎祥教授编写的第三版《编译原理》的PDF版本,在编译原理学习过程中的指导和作用。
何炎祥教授是编译原理领域的专家,他在本书中系统、全面地介绍了编译器的设计和实现原理,以及相关的理论和算法。
何教授用通俗易懂的语言将专业知识传达给读者,使得大家能够更容易地理解和掌握编译原理的核心概念和技术。
第三版《编译原理》的PDF版本是当前学习编译原理的第一选择。
该版本在前两版的基础上进行了内容的全面更新和扩充,具有更强的实用性和指导性。
全书分为八个章节,包括词法分析、语法分析、语义分析、中间代码生成、代码优化、代码生成、符号表管理和错误处理等。
每个章节都有详细的理论阐述和实践案例,供大家学习和实践使用。
《编译原理》第三版的PDF版本在内容上更加生动有趣,采用了图文并茂的方式进行讲解。
教材中通过生活中的例子和实际的编程任务,引领读者逐步学习和掌握编译原理的基本原理和方法。
这样的设计让抽象的编译原理问题更加具体化,增强了学习的兴趣和实践的动力。
该教材的PDF版本还具有较强的全面性和指导性。
无论是初学者还是专业人士,都能够从中找到自己所需的内容和解决方案。
《编译原理》第三版的PDF版本深入浅出地介绍了编译器的设计过程中所涉及到的各个环节和技术,包含了理论和实践的结合,为读者提供了全面而实用的编译原理学习资料。
总之,《编译原理》何炎祥第三版的PDF版本是一本生动、全面、有指导意义的编译原理教材。
无论是学习编译原理的初学者还是从事编译器开发工作的专业人士,都可以从中获得宝贵的知识和技能。
相信通过学习和运用该教材,读者们可以更好地理解和应用编译原理,为编程和软件开发领域做出更大的贡献。
编译原理 C语言 词法分析 实验 源码

编译原理实验报告 词法分析
南京信息工程大学 计算机与软件学院 软件工程 2009 级 1 班 54andy1@ 一.实验目的
#region 负数 算数减 算数减并赋值 case ANSIC.Character.MinusSign:
break; #endregion
#region 算数乘 算数乘并赋值 case ANSIC.Character.Asterisk:
if (index + 1 < SourceLines[row].Length && SourceLines[row][index + 1] == '+') { Result.Add(new Token(TokenTypes.MultiplyAsign, row, index, 2, "*=")); index++;
word.Append(SourceLines[row][index]); index++; while (index<SourceLines[row].Length) { if (SourceLines[row][index] >= '0' && SourceLines[row][index] <= '9')
编译原理实验报告 词法分析 1 / 19
一开始做词法分析的时候,单纯做词法分析,没有考虑到语法分析,所以没有架构好,在要做语法分析的 时候找不到合适的接口,这是第一个教训。
编译原理实验查填符号表含源代码和运行结果

编译原理实验查填符号表含源代码和运行结果公司内部档案编码:[OPPTR-OPPT28-OPPTL98-OPPNN08]《编译原理》实验报告实验1 查填符号表姓名学号班级计科1001班时间: 2012/3/22 地点:文波同组人:无指导教师:朱少林实验目的1、运用所学知识,选择语言、选择算法(数据结构),编程实现符号表管理程序。
2、熟悉编译过程,训练编写程序的能力,为后续实验积累经验。
实验内容1、运用所学知识,编程实现符号表管理程序。
读出源程序中与C语言词法规定相一致的标识符,并在符号表中进行查找,若存在则输出该标识符及其编号和位置;否则将其填入符号表,并分配编号,确定位置,输出该标识符。
2、输出标识符表。
实验环境软件:VC++实验前准备1、方案设计:①准备模拟数据:由于是识别符合c语言规定的标识符,故本实验中使用“测试文件.c”②写出c语言标识符的正规式定义:letter_→A|B|C|…Z|a|b|…z|_digit→0|1|…9 id→letter_(letter_|digit)*③画出不确定的有限自动机不确定的有限自动机如下:进行化简:A={1}B={2,3,4,5,9}C={3,4,5,6,8,9}D={3,4,5,7,8,9}状态转换表如下:状态letter_digitA BB C DC C DD C D进行化简:{A} {B,C,D}化简后的确定有限自动机如下:④程序思想:该实验重点是构造识别标识符的函数。
程序中,使用的数据结构如下:struct record{char name[20];};typedef struct record RECORD;record是用来记录标识符的名字,并且规定标识符的长度最大为20struct inforame)){j++;}ame,teststring);ine=j;p->length++;}2、程序设计#include ""#include ""#include ""struct record{char name[20];};typedef struct record RECORD;struct inforame)){j++;}ame,teststring);ine=j;p->length++;}printf("标识符%s在符号表的第%d行\n",teststring,j+1); fprintf(f,"%s\t%5d\n",teststring,j+1);","r");if (fp==NULL){printf("打开文件失败!");exit(0);}xt","w+");xt”xt”命令INFOR information;0’xt"}}xt","w+");xt"文件if(table==NULL){printf("文件打开失败!");exit (0);}int i=0;ame);fwrite(&[i], strlen(mark[i].name),1,table);fprintf(table,"%4d\n",i+1);xt”内容如下:include 1stdio 2h 3int 4_qq 5int 4temp 6char 7temp_s 8int 4search 9char 7str 10char 7c 11void 12main 13char 7str 10c 11int 4m 14i 15printf 16 please 17 input 18a 19 string 20 gets 21str 10puts 22 please 17 input 18the 23char 7you 24 search 9 c 11 getchar 25 m 14 search 9 str 10c 11if 26m 14printf 16 can 27not 28find 29else 30printf 16 the 23c 11you 24 search 9 is 31d 32n 33m 14int 4 search 9 char 7str 10char 7c 11int 4i 15for 34i 15str 10i 15i 15if 26str 10i 15c 11return 35i 15return 35存放符号表的文件“符号表.txt”内容如下:include 1stdio 2h 3int 4_qq 5char 7 temp_s 8 search 9 str 10c 11void 12 main 13m 14i 15printf 16 please 17 input 18 a 19string 20 gets 21 puts 22 the 23you 24 getchar 25 if 26can 27find 29else 30is 31d 32n 33for 34return 35使用的模拟数据“测试文件.c”如下:#include<>int _qq;int 3temp;char temp_s;int search(char str[80], char c);void main(){char str[80],c;int m,i;printf("please input a string:");gets(str);puts("please input the char you search");c=getchar();m=search(str,c);if(m==-1)printf("can not find");elseprintf("the c you search is %d\n",m);}int search(char str[80],char c){int i;for(i=0;str[i]!='\0';i++){if(str[i]==c){return(i);}}return -1;}分析:实验过程中最大的难题是文件的操作,因为之前关于文件的操作课程没有讲,再加上很久没写代码的原因,就先学了下文件操作,实验过程中最开始“结果.txt”总是空,后来知道原来是我在创建了该文件后就关闭了,在没有打开的情况下不能进行写入结果的操作;还有就是刚开始的“符号表.txt”每个符号后面都有不同数目的“烫”,经分析知道这种情况下每个标识符都是强制的长度一致,都是20(定义的标识符最大长度是20),这是因为向文件中写入数据时:fwrite(&[i],strlen(mark[i].name),1,table);我把每次写入的数据块长度设为了sizeof(record),而该结果是20,所以导致每个标识符长度是20.不过该实验还有一个地方需要改进,因为对于“23aa”这样的字符串“aa”按照规定应该不是一个标识符,而在这个试验中却也把“aa”识别为了一个标识符,本来想用一个char型history来记录上个读入字符来判断识别的字符串是不是以数字开头的某字符串的后部分,但是没成功,时间关系,我再思考下如何实现该功能。
3.5节 语法分析的自动生成-编译原理及实践教程(第3版)-黄贤英-清华大学出版社

%%
• 第二节是文法记号的声明,一般以%start S 的形式说明文法的开始符号,用%token
辅助过程
IF、DO、…、ID、… 的形式说明记号。记 号被YACC赋予了不会与任何字符值冲突的
数字值
• 数据类型、全局变量
等遵循C语言的定义, %{
可包含预处理语句等, 需要用%{和%}括起来
#include<stdio.h> %}
的最受欢迎的语法分析生成器
• Jflex——是一个Java的词法/语法分析生成器
• Jison ——JavaScript解析器。Jison 将一个上下文无关语
法作为输入,输出对应的JavaScript代码,类似Yacc
• Grammatica——C#和Java的语法剖析器生成器。相对于
其它一些类似的工具如yacc和ANTLR有了更好的改进:创 建了更好的注释和易读的源代码/拥有错误自动恢复并能 够详述错误信息/支持语法、词法测试与调试.
– YACC在对源文件进行编译时,将对所有的单词和非终 结符进行编码,并用该编码建立分析表和语法分析器 。单词的编码原则是:字符单词使用其对应的ASCII码 ,有名单词则由分析器进行编码。用户在对有名单词 进行命名时,一定要注意不要和使用该单词名的C源程 序中已有的宏名相同,否则在编译该C模块时是会产生 宏定义冲突的。
由Johnson等人在美国Bell实验室研制开发
• yacc生成的编译器主要是用C语言写成的语法解析
器(Parser),需要与词法分析器Lex一起使用, 再把两部份产生出来的C程序一并编译。
• yacc本来只在Unix系统上才有,GNU 版叫做 Bison。
现在已普遍移植到Windows及其他平台。
编译原理语法分析实验报告(含有源代码)

《编译原理》实验报告
四、实验过程原始记录(数据、图表、计算等)
输入begin a:=9;x:=2*3;b:=a+x end #
输出success
输入x:=a+b*c end #
输出error
五、实验结果及分析,以及心得体会
通过学习了语法分析,再经过实验,让我对语法分析有了深刻的认识和了解。
递归下降分析法,是一种确定的自顶向下分析技术,它的实现思想是,对文法中分别代表一种语法成分的每个非终结符号编写一个子程序,已完成非终结符号所对应的语法成分的分析任务。
在分析过程中调用一系列过程或函数,对源程序进行语法语义分析直到整个程序处理结束。
编译原理第三版王生原

编译原理第三版王生原编译原理是计算机科学中非常重要的一门课程,它涉及到编程语言的设计、编译器的构建以及程序的执行过程等方面。
《编译原理》第三版由王生原编著,是一本经典的教材,被广泛应用于计算机相关专业的教学和研究中。
本书共分为13章,内容涵盖了编译原理的基本概念、词法分析、语法分析、语法制导翻译、中间代码生成、运行时环境等多个方面。
每一章都详细介绍了相关的理论知识,并通过大量的实例和案例分析,帮助读者深入理解和掌握编译原理的核心内容。
在第一章中,王生原介绍了编译原理的基本概念和编译器的工作原理。
他首先阐述了编译器在程序设计和执行过程中的重要作用,然后详细介绍了编译器的基本结构和工作流程。
通过对编译器的整体框架和各个模块的功能进行分析,读者可以清晰地了解编译器的工作过程,为后续的学习打下坚实的基础。
接下来的几章分别介绍了词法分析和语法分析的原理和方法,包括正规表达式、有限自动机、上下文无关文法等内容。
王生原通过丰富的例子和图表,生动地阐述了这些复杂概念,帮助读者理解和掌握这些重要的知识点。
在中间代码生成和运行时环境这两个关键章节中,王生原详细介绍了中间代码的生成过程和运行时环境的组织结构,为读者展示了编译器如何将高级语言程序翻译成目标代码,并在目标机器上执行的全过程。
除了理论知识的讲解,本书还包括了大量的实例和案例分析,帮助读者将理论知识应用到实际的编译器设计和实现中。
通过这些实例,读者可以更加直观地了解编译原理的应用,提高自己的实际编程能力。
总的来说,王生原的《编译原理》第三版是一本很好的教材,它系统全面地介绍了编译原理的基本概念和核心技术,适合计算机相关专业的学生和从业人员阅读和参考。
通过学习本书,读者可以全面深入地了解编译原理的知识体系,提高自己的编程能力,为今后的学习和工作打下坚实的基础。
编译原理-预测分析法(附源码)(1)知识讲解

预测分析法实验报告一、实验项目名称预测分析法二、实验目的根据某一LL(1)文法编制调试预测分析程序,以便对任意输入的符号串进行分析。
本次实验的目的主要是加深对预测分析法的理解。
三、实验环境Windows 10Microsoft Visual Studio 2015四、实验内容本次实验的LL(1)文法为表达式文法:E→E+T | TT→T*F | FF→i | (E)编写识别表达式文法的合法句子的预测分析程序,对输入的任意符号串,给出分析过程及分析结果。
分析过程要求输出步骤、分析栈、剩余输入串和所用产生式。
如果该符号串不是表达式文法的合法句子,要给出尽量详细的错误提示五、源程序清单、测试数据、结果#include<iostream>#include<string>using namespace std;const int NUM = 20;//初始化的栈的大小//非终结符数组集char Var[5] = { 'E','R','T','M','F' };//终结符数组集char Ter[6] = { 'i','+','*','(',')','#' };string pred[5][6] ={ { "TR","","","TR","","" },{ "","+TR","","","@","@" },{ "FM","","","FM","","" },{ ""," @","*FM","","@","@" },{ "i","","","(E)","","" } };typedef struct {char *top;char *base;int stacksize;int num;}Stack;// 栈结构体void init(Stack *ss) {//初始化栈ss->base = (char *)malloc(NUM * sizeof(char));if (!ss->base)exit(1);ss->top = ss->base;ss->stacksize = NUM;ss->num = 0;}void push(Stack *ss, char c) {//入栈操作if (ss->top - ss->base >= ss->stacksize)exit(1);*(ss->top) = c;ss->top++;ss->num++;}void pop(Stack *ss) {//出栈操作if (ss->top == ss->base)exit(1);ss->top--;ss->num--;}char getTop(Stack *ss) {//取得栈顶元素if (ss->top == ss->base)exit(1);return *(ss->top - 1);}int isT(char c) {//判断是否为终结符int i = 0;int ret = 0;for (i = 0; i<6; i++) {if (Ter[i] == c){ret = 1; break;}}return ret;}string isInPred(char v, char t) {//查找预测分析表,并返回产生式右部int i, j;for (i = 0; i<5; i++){if (Var[i] == v)break;}for (j = 0; j<6; j++){if (Ter[j] == t)break;}if (pred[i][j] !=""){return pred[i][j];}elsereturn"";}void displayStack(Stack *stack) { //输出分析站的内容string str;int i = 0;Stack ss = *stack;while (ss.num != 0){str += getTop(&ss);pop(&ss);}for (i = str.length() - 1; i >= 0; i--){cout << str.at(i);}}void predict(Stack stack, string input)//预测分析总函数{int a = 1;char b;char ctop;//当前栈顶符号char cinput;//当前输入符号int i = 0, j = 0, count = 0;int error = 0;cout <<"步骤"<<'\t'<<"栈"<<'\t'<<"输入缓冲区"<<'\t'<<"所用的产生式"<< endl;cout << count++ <<'\t';displayStack(&stack);cout <<'\t'<<input<<'\t'<<""<< endl;while (getTop(&stack) != '#'){string produce = "";ctop = getTop(&stack);cinput = input.at(i);if (isT(ctop))//栈顶符号为终结符{if (ctop == cinput){pop(&stack);i++;}else{error = 1; break;}produce +="\"";produce += ctop;produce +="\"匹配";}else//栈顶符号位非终结符{string str = isInPred(ctop, cinput);if (str !=""){pop(&stack);if (str !="@"){for (j = str.length() - 1; j >= 0; j--)push(&stack, str.at(j));}produce += ctop;produce +="→";produce += str;}else{error = 1; break;}}//栈顶符号位非终结符cout << count++ <<'\t';displayStack(&stack);cout <<'\t'<<input.substr(i) <<"\t\t"<< produce << endl;}if (error)cout <<"不接受"<< endl;elsecout <<"接受"<< endl;}void main(){while (1) {int sel;//继续或者退出程序选择string input;//输入串int i = 0, j = 0;Stack stack;init(&stack);push(&stack, '#');push(&stack, 'E');cout <<"----------------文法如下--------------"<< endl;cout <<"E→E+T | T"<< endl;cout <<"T→T*F | F"<< endl;cout <<" F→i | (E)"<< endl;cout <<"----------------请输入表达式(以#结尾)--------------"<< endl;cin >> input;cout <<"“R表示“E'”,”M“表示“T'”,”@“表示“空”"<< endl;predict(stack, input);sel=0;if (sel == 0)exit(0);elsesystem("cls");}}六、实验小结和思考本次实验的文法是写在程序中的,不可以自行输入,难度不是很难,并没有太大问题,只是一些未初始化的小问题。
编译原理实验报告——词法分析器(内含源代码)

编译原理实验(一)——词法分析器一.实验描述运行环境:vc++2008对某特定语言A ,构造其词法规则。
该语言的单词符号包括:12状态转换图3程序流程:词法分析作成一个子程序,由另一个主程序调用,每次调用返回一个单词对应的二元组,输出标识符表、常数表由主程序来完成。
二.实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。
同时增强编写和调试程序的能力。
三.实验任务编制程序实现要求的功能,并能完成对测试样例程序的分析。
四.实验原理char set[1000],str[500],strtaken[20];//set[]存储代码,strtaken[]存储当前字符char sign[50][10],constant[50][10];//存储标识符和常量定义了一个Analyzer类class Analyzer{public:Analyzer(); //构造函数 ~Analyzer(); //析构函数int IsLetter(char ch); //判断是否是字母,是则返回 1,否则返回 0。
int IsDigit(char ch); //判断是否为数字,是则返回 1,否则返回 0。
void GetChar(char *ch); //将下一个输入字符读到ch中。
void GetBC(char *ch); //检查ch中的字符是否为空白,若是,则调用GetChar直至ch进入一个非空白字符。
void Concat(char *strTaken, char *ch); //将ch中的字符连接到strToken之后。
int Reserve(char *strTaken); //对strTaken中的字符串查找保留字表,若是一个保留字返回它的数码,否则返回0。
void Retract(char *ch) ; //将搜索指针器回调一个字符位置,将ch置为空白字符。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Scanner:#include <stdio.h>#include <stdlib.h>#include <string.h>#define _KEY_WORD_END "waiting for your expanding"typedef struct{int typenum;char * word;} WORD;char input[255];char token[255]="";int p_input;int p_token;char ch;char* KEY_WORDS[]={"main","int","char","if","else","for","while",_KEY_WORD_END}; WORD* scaner();void main(){int over=1;WORD* oneword=new WORD;printf("Enter Your words(end with $):");scanf("%[^$]s",input);p_input=0;printf("Your words:\n%s\n",input);while(over<1000&&over!=-1){oneword=scaner();if(oneword->typenum<1000)printf("(%d,%s)",oneword->typenum,oneword->word);over=oneword->typenum;}printf("\npress # to exit:");scanf("%[^#]s",input);}char m_getch(){ch=input[p_input];p_input=p_input+1;return (ch);}void getbc(){while(ch==' '||ch==10){ch=input[p_input];p_input=p_input+1;}}void concat(){token[p_token]=ch;p_token=p_token+1;token[p_token]='\0';}int letter(){if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')return 1;else return 0;}int digit(){if(ch>='0'&&ch<='9')return 1;else return 0;}int reserve(){int i=0;while(strcmp(KEY_WORDS[i],_KEY_WORD_END)){ if(!strcmp(KEY_WORDS[i],token)){return i+1;}i=i+1;}return 10;}void retract(){p_input=p_input-1;}char* dtb(){return NULL;}WORD* scaner(){WORD* myword=new WORD;myword->typenum=10;myword->word="";p_token=0;m_getch();getbc();if(letter()){while(letter()||digit()){concat();m_getch();}retract();myword->typenum=reserve();myword->word=token;return(myword);}else if(digit()){while(digit()){concat();m_getch();}retract();myword->typenum=20;myword->word=token;return(myword);}else switch(ch){case '=': m_getch();if (ch=='='){myword->typenum=39;myword->word="==";return(myword);}retract();myword->typenum=21;myword->word="=";return(myword);break;case '+': myword->typenum=22;myword->word="+";return(myword);break;case '-': myword->typenum=23;myword->word="-";return(myword);break;case '*': myword->typenum=24;myword->word="*";return(myword);break;case '/': myword->typenum=25;myword->word="/";return(myword);break;case '(': myword->typenum=26;myword->word="(";return(myword);break;case ')': myword->typenum=27;myword->word=")";return(myword);break;case '[': myword->typenum=28;myword->word="[";return(myword);break;case ']': myword->typenum=29;myword->word="]";return(myword);break;case '{': myword->typenum=30;myword->word="{";return(myword);break;case '}': myword->typenum=31;myword->word="}";return(myword);break;case ',': myword->typenum=32;myword->word=",";return(myword);break;case ':': myword->typenum=33;myword->word=":";return(myword);break;case ';': myword->typenum=34;myword->word=";";return(myword);break;case '>': m_getch();if (ch=='='){myword->typenum=37;myword->word=">=";return(myword);}retract();myword->typenum=35;myword->word=">";return(myword);break;case '<': m_getch();if (ch=='='){myword->typenum=38;myword->word="<=";return(myword);}retract();myword->typenum=36;myword->word="<";return(myword);break;case '!': m_getch();if (ch=='='){myword->typenum=40;myword->word="!=";return(myword);}retract();myword->typenum=-1;myword->word="ERROR";return(myword);break;case '\0': myword->typenum=1000;myword->word="OVER";return(myword);break;default: myword->typenum=-1;myword->word="ERROR";return(myword);}}Parsing:#include<stdio.h>#include<string.h>#include<stdlib.h>int syn,p_input,p_token,kk;char ch;char input[100];char token[100]="";char* key_words[]={"begin","if","then","while","do","end"}; int expression();void m_getch();int letter();int digit();int compare();void c_token();void scaner();void main(){FILE *fin;char buffer[100];int size;if((fin=fopen("test.txt","r"))==NULL){printf("Cannot open the file!\n");exit(-1);}fin=fopen("test.txt","r");while(fgets(buffer,100,fin)!=NULL){strcat(input,buffer);}lrparser();printf("\npress # to exit:\n");scanf("%[^#]",input);fclose(fin);}{ scaner();if(syn==1){scaner();yucu();if(syn==6){scaner();if((syn==0)&&(kk==0)){printf("Success\n");return 1;}}else{if(kk!=1)printf("no end error\n");kk=1;return 0;}}else{printf("no begin error\n");kk=1;return 0;}}int yucu(){statement();while (syn==29){scaner();statement();}return 1;}{p_token=0;m_getch();while(ch==' '||ch==10)m_getch();if(letter()){while(letter()||digit()){c_token();m_getch();}p_input--;syn=compare();}else if(digit()){while(digit()){c_token();m_getch();}p_input--;syn=11;}else switch(ch){case '=': c_token();m_getch();if(ch=='='){syn=24;c_token();}else{p_input--;syn=21;}break;case '<': c_token();m_getch();if(ch=='=')syn=25;c_token();}else if(ch=='>'){syn=26;c_token();}else{ p_input--;syn=22;}break;case '>': c_token();m_getch();if(ch=='='){syn=27;c_token();}else{p_input--;syn=23;}break;case '+': syn=13;c_token();break;case '-': syn=14;c_token();break;case '*': syn=15;c_token();break;case '/': syn=16;c_token();break;case '(': syn=17;c_token();break;case ')': syn=18;c_token();break;case '{': syn=19;c_token();break;case '}': syn=20;c_token();break;case ';': syn=29;c_token();break;case '#': syn=0;break;default : syn=-1;c_token();}}void m_getch(){ch=input[p_input];p_input++;}void c_token(){token[p_token]=ch;p_token++;token[p_token]='\0';}int compare(){int n;for(n=0;n<6;n++){if(strcmp(key_words[n],token)==0)return n+1;}return 10;}int letter(){if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')return 1;else return 0;}int digit(){if(ch>='0'&&ch<='9')return 1;else return 0;}int expression(){term();while (syn==13||syn==14){scaner();term();}return 1;}int factor(){if(syn==10||syn==11)scaner();else if(syn==17){scaner();expression();if (syn==18){scaner();}else { printf("输入错误\n");kk=1;return 0;} }else {printf("输入表达式错误\n");kk=1;return 0;} return 1;}int term(){factor();while(syn==15||syn==16){scaner();factor();}return 1;}int statement(){if(syn==10){scaner();if (syn==21){scaner();expression();}else {printf("输入赋值错误\n");kk=1;} }else {printf("输入语句错误\n");kk=1;}return 1;}。