DO-WHILE循环语句的翻译程序设计
- 格式:doc
- 大小:313.00 KB
- 文档页数:28
do-while语句的语法格式及其流程`do-while` 语句是一种循环语句,它在执行循环体之前先执行一次条件判断。
这意味着,无论条件是否满足,循环体至少会被执行一次。
下面是`do-while` 语句的语法格式和执行流程:```cppdo {// 循环体} while (条件表达式);```- `do` 后面紧跟着循环体,用花括号`{}` 括起来,循环体是需要重复执行的语句块。
- `while` 后面跟着条件表达式,条件表达式返回一个布尔值。
如果条件为真,循环会继续执行;如果条件为假,循环结束。
执行流程如下:1. 执行`do` 后的循环体。
2. 执行完循环体后,计算`while` 后的条件表达式。
3. 如果条件表达式为真,则回到步骤1,重新执行循环体;如果条件表达式为假,则退出循环。
下面是一个简单的C++ 示例,演示了`do-while` 语句的用法:```cpp#include <iostream>int main() {int count = 0;do {std::cout << "Count: " << count << std::endl;count++;} while (count < 5);return 0;}```这个例子会输出以下内容:```Count: 0Count: 1Count: 2Count: 3Count: 4```即使条件`count < 5` 在第一次循环后变为假,`do-while` 语句仍然执行了一次循环体。
DO-WHILE循环语句的翻译程序设计(递归下降法、输出三地址表示)1.系统描述1.1目的通过设计,编制,调试一个DO-WHILE循环语句的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的此法检查和分析。
1.2设计内容及步骤对DO 语句WHILE 条件(1)写出符合给定的语法分析方法的文法及属性文法。
(2)完成题目要求的中间代码三地址表示的描述。
(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。
(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
1.3 初始条件理论:学完编译课程,掌握一种计算机高级语言的使用。
实践:计算机实验室提供计算机及软件环境。
如果有计算机可以在其上进行设计。
1.4 开发平台Windows环境下使用Visual C++2.文法及属性文法的描述2.1 DO-WHILE循环语句的文法文法G(S)如下:S->do{A}while(P);A->id=E;E->TE'E'->+TE' | -TE' | eT->FT'T'->*FT' | /FT' | eF->(E) | idP->E rop idrop-> > | < | >= | <= | != | ==2.2 DO-WHILE循环语句的属性文法3.语法分析方法描述及语法分析表设计3.1语法分析方法3.11递归下降法递归下降法是比较简单直观易于构造的一种语法分析方法。
递归下降法的主要思想是:对每个非终结符按其产生式结构写出相应语法分析递归过程,每个过程的功能是识别由该非终结符推出的串,当某非终结符的产生式有多个候选时能够按LL(1)形式可唯一确定选择某个候选式进行推导。
因为文法递归相应子程序也递归,子程序的结构与产生式结构几乎一致。
(二)DO-WHILE循环语句的翻译程序设计(简单优先法、输出四元式)一、1.简单优先法的基本思想根据优先关系的定义,将简单优先文法中各文法符号之间的这种关系用一个矩阵表示,称作简单优先矩阵。
PDA读入一个单词后,比较栈顶符号和该单词的优先级,若栈顶符号优先级低于该单词,继续读入;若栈顶符号优先级高于或等于读入符号,则找句柄进行归约,找不到句柄就继续读入。
直到最后栈内只剩下开始符号,输入串读到“#”为止。
此时识别正确。
可分点描述如下:(1)、对句型中相邻的文法符号规定优先关系,以寻找句型中的句柄;(2)、规定句柄内各相邻符号之间具有相同的优先级;(3)、规定句柄两端符号优先级要比位于句柄之外而又和句柄相邻的符号的优先级高,以先归约句柄;(4)、对于文法中所有符号,只要它们可能在某个句型中相邻,就要为它们规定相应的优先关系,若某两个符号永远不可能相邻,则它们之间就无关系.2.简单优先矩阵用于表示文法符号之间的简单优先关系的矩阵。
3.简单优先法的优缺点优点:技术简单,当做简单优先矩阵是要求较短。
缺点:适用范围小,分析表尺寸太大。
二、源代码实现:#include<iostream>#define MAX 35#include<list>#include<string>#include<fstream>using namespace std;#define TABLE_LEN 8#define STR_LEN 256int zhlen;char sTable[TABLE_LEN+1] = {"+-*/()i#"};//顺序索引int ShipTable[TABLE_LEN][TABLE_LEN] = //优先表{{ 1, 1,-1,-1,-1, 1,-1, 1},{ 1, 1,-1,-1,-1, 1,-1, 1},{ 1, 1, 1, 1,-1, 1,-1, 1},{ 1, 1, 1, 1,-1, 1,-1, 1},{-1,-1,-1,-1,-1, 0,-1,-2},{ 1, 1, 1, 1,-2, 1,-2, 1},{ 1, 1, 1, 1,-2, 1,-2, 1},{-1,-1,-1,-1,-1,-2,-1, 0}};char X,a;char VN[11]={'K','L','P','S','E','G','T','R','F','Q','\0'};char VT[15]={'i','=','<','>','+','-','*','/','(',')','d','w',';','#','\0'};charp[18][6]={"dLwS\0","SP\0",";SP\0","\0","iQE\0","TG\0","+TG\0","-TG\0","\0","FR\0", "*FR\0","/FR\0","\0","(E)\0","i\0","=\0","<\0",">\0"};char stack[MAX];char queue[MAX];int sp,front;intM[10][14]={ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,-1,-1},{1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,2,-1},{4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},{5,-1,-1,-1,-1,-1,-1,-1,5,-1,-1,-1,-1,-1},{-1,-1,-1,-1,6,7,-1,-1,-1,-1,-1,8,8,8},{9,-1,-1,-1,-1,-1,-1,-1,9,-1,-1,-1,-1,-1},{-1,-1,-1,-1,12,12,10,11,-1,-1,-1,12,12,12},{14,-1,-1,-1,-1,-1,-1,-1,13,-1,-1,-1,-1,-1},{-1,15,16,17,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},};int f=0; int count=0;int c=0;char arr_i[MAX];char var[MAX]; //表格管理int td[MAX];int t=0;int opd=-1;int opr=-1;int id=0;int d=0;char arr[MAX][4];//存放待输出的四元式//char keyword[2][7]={"do\0","while\0"};bool IsCharInStr(char c,char s[]){for(int i=0;s[i]!='\0';i++){if(s[i]==c)return true;}return false;}int GetIndex(char s[],char c){for(int i=0;s[i]!='\0';i++){if(c==s[i])return i;}return -1;}//string GetSubString(char s[],int from,int to){string st;for(int i=from;i<to;i++){st+=s[i];}return st;}/*******************************************翻译赋值表达式********************************************/void translatefuzhi(char *sInput){//栈结构的初始化char Stack[STR_LEN]={0};int index = 0;int top = 1;Stack[0] = '#';list<char> rPolish;list<string> Num;int begin=0;while(sInput[begin]!='='){if(IsCharInStr(sInput[begin],sTable)){cout<<"Equal expression is illegal!"<<endl;return ;}begin++;}Num.push_back(GetSubString(sInput,0,begin));int now = begin+1;int before = begin;rPolish.push_back('i');while(sInput[now]!='\0'){if(IsCharInStr(sInput[now],sTable)){char temp[3]={0};if(now-before>1){temp[0] = 'i';temp[1] = sInput[now];Num.push_back(GetSubString(sInput,before+1,now));}else{temp[0] = sInput[now];}int i=0;while(temp[i]!=0){int left = GetIndex(sTable,Stack[index]);int right = GetIndex(sTable,temp[i]);switch(ShipTable[left][right]){case -1://移入Stack[top++] = temp[i];index = top-1;i++;break;case 0://脱括号if(Stack[index]=='('){Stack[top++] = ')';Stack[index] = 'E';top = index+1;index--;}else//规约{if(top!=2){return;}rPolish.push_back('=');list<char>::iterator iter;list<string>::iterator siter=Num.begin();string fuzhi[256];int d=0,m;for(iter=rPolish.begin();iter!=rPolish.end();iter++){if(*iter=='i'){fuzhi[d++]=*siter;siter++;}else{fuzhi[d++]=*iter;}}m=d;string op1,op2;int flag,xiabiao=0;for(d=0;d<m;d++)cout<<"("<<fuzhi[d]<<","<<op1<<","<<op2<<","<<"T"<<xiabiao<<")"<<endl;fuzhi[d] = "T";fuzhi[d]+=(xiabiao+'0');xiabiao++;}//cout<<fuzhi[d];}return;}i++;break;case 1://归约if(Stack[index]=='i'){rPolish.push_back('i');Stack[index] = 'E';index--;}else{rPolish.push_back(Stack[index]);Stack[index-1] = 'E';top = index;index-=2;}break;default:return;}}before=now;}now++;}}int len(char str[]){int i=0;while(str[i]!='\0')i++;return i;}int index(char ch,char str[]){int i=0;while(str[i]!='\0'){if(ch!=str[i])i++;else break;}if(str[i]=='\0')return -1;return i;}void err(int n){if(n==1)cout<<"字符不匹配"<<endl;else if(n==2)cout<<"字符没有出现在产生式中"<<endl;else if(n==3)cout<<"没有找到合适的¨选产式"<<endl;else cout<<"该句子是文法语言的句子"<<endl;}void print(){cout<<"(";if(count<10)cout<<'0';cout<<count<<")";int i;for(i=0;i<=sp;i++)cout<<stack[i];for(;i<=20;i++)cout<<" ";for(i=0;i<front;i++)cout<<" ";for(;queue[i]!='#';i++)cout<<queue[i];cout<<queue[i];for(;i<=20;i++)cout<<" ";}void semantic(){if(VT[opr]=='='){arr[d][0]='=';arr[d][1]=arr_i[opd];arr[d][2]=id;arr[d][3]='--';id++;} else if(opr==-2){arr[d][0]='=';arr[d][1]=id-1;arr[d][2]=arr_i[opd];arr[d][3]='--';}else {arr[d][0]=VT[opr];arr[d][1]=arr_i[opd];arr[d][2]=id;if(VT[opr]!='<'&&VT[opr]!='>')arr[d][3]=id-1;else arr[d][3]=id+1;id++;}d++;}void syntax(){//语法分析int n;count++;print();X=stack[sp];a=queue[front];if(X=='#'&&a=='#')f=4;if(X<'A'||X>'Z'){if(X==a){sp--;front++;if(a!='i'){if(a!='d'&&a!='w'&&a!=';'&&a!='#'){opr=index(a,VT);semantic();}else if(a==';'||a=='w'||a=='#'){opr=-2;semantic();}cout<<'\t'<<'\''<<a<<"'匹配"<<endl;}else {opd=c;cout<<'\t'<<'\''<<arr_i[c++]<<"'匹配"<<endl;}}else f=1;}else {int tx=index(X,VN);int ta=index(a,VT);n=M[tx][ta];td[t++]=M[tx][ta];if(ta==-1){f=2;cout<<a<<endl;}else if(n==-1)f=3;else {sp--;cout<<'\t'<<X<<"->";if(len(p[n])!=0){for(inti=len(p[n])-1;i>=0;i--){stack[++sp]=p[n][i];cout<<p[n][len(p[n])-1-i];}cout<<endl;}else cout<<"空串"<<endl;}}if(f==0)syntax();else {td[t]='-1';err(f);}}void lexical(){ //词法分析int i,j,d;char ch;j=d=0;for(i=0;var[i]!='#';i++){ch=var[i];if(ch=='d'&&var[i+1]=='o'){cout<<"do"<<'\t'<<"keword"<<endl;queue[j++]='d';i+=1;}else if(ch=='w'){ch=var[i+1];if(ch=='h'){ch=var[i+2];if(ch=='i'){ch=var[i+3];if(ch=='l'){ch=var[i+4];if(ch=='e'){ch=var[i+5];}}}}cout<<"while"<<'\t'<<"keyword"<<endl;queue[j++]='w';i+=4;}else if(index(ch,VT)<=0){if(ch!='{'&&ch!='}'&&ch!='('&&ch!=')'){cout<<ch<<'\t'<<"variable:i["<<d++<<"]"<< endl;arr_i[d-1]=ch;queue[j++]='i';}else cout<<ch<<'\t'<<"bound"<<endl;}else if(index(ch,VT)>0){cout<<ch<<'\t'<<"operator"<<endl;queue[j++]=ch;} }queue[j]='#';for(i=0;queue[i]!='#';i++)cout<<queue[i];cout<<endl;}int main(){int i=0,j=0;int len,length;char temp;char S='K';sp=front=0;stack[0]='#';sp++;stack[1]='K';cout<<" ****************************"<<endl;cout<<" * DO-WHILE循环语句*"<<endl;cout<<" * (简单优先法输出四元式) *"<<endl;cout<<" ****************************"<<endl;ifstream table;table.open("dowhile.txt");if(!table){cout<<"error!";}table.seekg(0,ios::end);length = table.tellg();table.seekg(0,ios::beg);while(length!=table.tellg()){table.read((char*)&temp,1);var[i]=temp;i++;if(var[i]==' ')i--;if(var[i]=='#')break;}table.close();len=i;var[i]='\0';cout<<"词法分析"<<endl;lexical();char fuzhi[20];int flag1,fuzhilen;int s=0; for(i=0;i<len;i++){if(var[i]==';'){flag1=i;}}fuzhilen=flag1-2;for(i=3;i<flag1;i++){fuzhi[s++]=var[i];}fuzhi[s]='#';char shuru;char zh[100];int kaishi=0; zh[0]='d';for(kaishi=1;kaishi<s+1;kaishi++){zh[kaishi]=fuzhi[kaishi-1];}zh[kaishi++]=';';zh[kaishi++]='W';for(i=flag1+8;i<len;i++){if(var[i]=='}')break;else{zh[kaishi++]=var[i];}}zh[kaishi++]='#';zhlen=kaishi;cout<<"输出四元式"<<endl;cout<<"do"<<endl;translatefuzhi(fuzhi);cout<<"("<<var[flag1+9]<<","<<var[flag1+8]<<","<<var[flag1+10]<<","<<"T2"<<") "<<endl;cout<<"if T2=true goto T0"<<endl;return 0;}三、测试结果:词法分析部分:输出四元式:四、课程小结:这次编译原理课程设计的题目是用简单优先分析法进行DO-WHILE循环语句的语法分析,并输出四元式.设计的特点是利用定义每个终极符和非终极符之间优先关系,来进行符号的移进与规约,如果栈顶符号优先级低于该单词,继续读入;若栈顶符号优先级高于或等于读入符号,则找句柄进行归约,找不到句柄就继续读入。
WHILE循环语句的翻译程序设计(递归下降法、输出三地址表示)1 系统描述按照课程设计的要求,写一个能识别while循环语句的文法,通过一定的变换使它符合递归下降法的要求,然后按照这个文法编写一个程序,该程序能识别输入的语句是否符合while语句的文法,或者能不能通过文法的开始符号推导出该语句。
该程序应该包括词法分析器,能对输入的语句进行词法分析,然后再对结果进行语法分析。
词法分析器应能识别关键字,标示符,常量,操作符等。
该程序的语法分析器能对输入的语法进行分析,判断输入语句能否满足while循环语句的文法。
通过递归下降的方法对语句进行分析,看能否通过开始符号推导出来。
该程序的语义分析器就是对分析结果进行输出,要求输出结果是三地址形式的。
2 文法及属性文法的描述2.1文法描述语句 > ::= while (< 条件表达式 > (< 赋值语句 > | 语句 ><条件表达式> ::= (<标识符>|<无符号整数>)<条件运算符> (<标识符>|<无符号整数><标识符> ::= <字母> (<字母>|<数字><条件运算符> ::= > | < | =<无符号整数> ::= <数字>(<数字><赋值语句> ::= <标识符>=(<标识符> | <数字> <算术运算符> (<标识符> | <数字><算术运算符> ::= + | - | * | /<赋值语句> ::= <标识符>=<标识符> | <数字>2.2递归文法while语句文法:S -> while (B S | i=EB -> E relop Erelop -> < | = | >E -> E+E | E-E | E*E | E/E | (E | i | n在编写程序的时候用到的是递归下降法,而递归下降法对文法的要求是不能包含左递归,对上述的文法进行消除左递归之后,得到如下的递归文法:S -> while (B S | i=EB -> E relop Erelop -> < | = | >E -> (EF | iF | nFF -> +EF | -EF | *EF | /EF | ε2.3属性文法的描述产生式属性文法S -> while (B S1S.begin:=newlabel;S.next:=newlabel;B.true:=newlabel;B.false:=S.next;S1.next:=S.begin;S.code:=gen(S.begin, ‘:’ || B.code||gen(S.true, ‘:’ ||S1.code || gen(‘goto’,S.begin ||gen(B.false, ‘:’|| gen(‘goto Lnext’;B -> E1 relop E2 B.place:=newlabel;B.code:=E1.code || relop.code ||E2.code ||gen(B.place ‘:=’ , E1.place , r elop.place , E2.place;relop -> < | =relop.place:=newlabel;| >relop.code:=gen(‘<’||gen(‘=’||gen(‘>’;E -> (E1F E.place:=newlabel;E.code:=E1.code ||F.code ||gen(E.place ‘:=’ ,‘(’, E1.place , ‘’, F.place;E -> iF E.palce:=newlabel;E.code:=i.code ||F.code ||gen(E.palce ‘:=’ ,i.place , F.place;E -> nF E.place:=newlabel;E.code:=n.code ||F.code ||gen(E.place ‘:=’ , n.place , F.place;F -> +EF1 F.place:=newlabel;F.code:=E.code || F1.code ||gen(F.place‘:= + ’, E.place , F1.place;F -> -EF1 F.place:=newlabel;F.code:=E.code || F1.code ||gen(F.place‘:= - ’, E.place , F1.place;F -> *EF1 F.place:=newlabel;F.code:=E.code || F1.code ||gen(F.place‘:= * ’, E.place , F1.place;F -> /EF1 F.place:=newlabel;F.code:=E.code || F1.code ||gen(F.place‘:= / ’, E.place , F1.place;F -> ε F.place:=newlabel;F.code:=gen(F.code‘:= ε’;图1 属性文法3 语法分析方法描述按照递归下降分析技术,递归下降识别程序是由一组子程序组成,每个子程序对应于一个非终结符号。
do while循环语句顺序
`do-while` 循环语句是一种循环结构,它会先执行循环体,然后检查循环条件。
循环体至少会被执行一次,即使初始时循环条件为false。
`do-while` 循环的基本形式如下:
```c
do {
// 循环体
} while (循环条件);
```
执行流程顺序如下:
1. 执行循环体。
2. 检查循环条件。
3. 如果循环条件为真(true),则继续执行循环体,然后再次检查循环条件。
4. 如果循环条件为假(false),则退出循环,继续执行后续代码。
`do-while` 循环适用于那些至少要执行一次循环体的情况。
以下是一个简单的示例,演示了`do-while` 循环的使用:
```c
#include <stdio.h>
int main() {
int i = 0;
do {
printf("%d ", i);
i++;
} while (i < 5);
return 0;
}
```
这个例子中,`do-while` 循环会输出数字0 到4。
即使`i` 的初始值是0,而循环条件是`i < 5`,循环体还是会被执行一次。
DO-WHILE循环语句的翻译程序设计(LR方法、输出三地址表示)1.系统描述1.1设计目的通过设计、编制、调试一个DO-WHILE循环语句的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。
1.2设计内容及步骤对循环语句:DO〈赋值语句〉WHILE 〈表达式〉按给定的题目写出符合自身语法分析方法要求的文法和属性文法描述。
(1)按给定的题目给出语法分析方法的思想及分析表设计。
(2)按给定的题目给出中间代码序列的结构设计。
(3)完成相应的词法分析、语法分析和语义分析程序设计。
(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
2文法的描述本程序所用的文法如下:G[S]:(1)S->do{E;}while(B) {if B.true goto B.true else goto B.false;}(2)B->I1 rop I2 {B.type=bool;B.val=I1.val rop I2.val;}(3)E->I1=I2 op I3 {I1.val=I2.val op I3.val;}(4)I->id {I.val=id.val;}注意:rop is < or >,op is +,-,*,/, id is any number or identifier由上可知,非终结符B表示布尔表达式,E表示赋值表达式3.语法分析方法描述及语法分析表设计3.1语法分析方法描述本实验采用LR分析方法对DO-WHILE语句进行语法分析。
LR分析法是一种能根据当前分析栈中的符号串(通常以状态表示)和向右顺序查看输入串的K个(K>=0)符号就能惟一的确定分析器的动作是移进还是归约和用哪个产生式归约,因而也就能惟一的确定句柄。
LR分析法的归约过程是规范推导的逆过程,所以LR分析过程是一种规范过程。
一个LR分析器由3个部分组成:总控程序,也可以称为驱动程序。
dowhile循环语句用法1. 嘿呀,你知道 do while 循环语句怎么用吗?就像你一直往前走,直到遇到特定条件才停下来。
比如说,你想要让用户一直输入直到输入正确,那就可以用 do while 循环呀!“do { 获取用户输入; } while (输入不正确);”,是不是很神奇呀!2. 哎呀,do while 循环语句可有意思啦!它就像一场冒险,先行动起来,然后再看条件决定要不要继续呢。
好比你在找宝藏,先找,然后看是不是找到了,没找到就接着找!“do { 尝试打开宝箱; } while (宝箱未打开);”,妙不妙呀!3. 告诉你哦,do while 循环语句真是个好东西呢!这就像是打游戏,先出招,然后判断能不能过关。
比如说统计输入的数字总和,直到输入负数就停止,“do { 输入数字; 总和 += 数字; } while (数字不小于0);”,是不是超好用呀!4. 哇塞,do while 循环语句的用法你可得搞清楚呀!它就如同你在跑步,先跑一段,然后看符不符合要求。
像是计算从 1 开始到多少累加和超过100,“do { 当前数++; 累加和 += 当前数; } while (累加和<= 100);”,多有趣呀!5. 嘿,do while 循环语句的魅力可大啦!它好比是你去尝试做一件事,做完看看情况,不行再接着做。
就像检查输入是否为偶数,“do { 输入数字; } while (数字不是偶数);”,这方法简直绝了!6. 你看,do while 循环语句是不是特别神奇呀!它就像一个执着的人,先做了再说,然后看结果决定下一步。
假设要反复询问是否喜欢编程,“do { 询问是否喜欢; } while (回答否);”,是不是让你大开眼界呢!我觉得 do while 循环语句是非常实用且有趣的,它能让我们的程序更灵活,让我们能更轻松地处理一些先执行后判断的情况。
课程设计题目WHILE循环语句的翻译程序设计(递归下降法、输出三地址表示)学院计算机科学与技术学院专业计算机科学与技术班级0806姓名张方纪指导教师郭羽成2010 年 1 月7 日课程设计任务书学生姓名:张方纪专业班级:计算机0806班指导教师:郭羽成工作单位:计算机科学与技术学院题目: WHILE循环语句的翻译程序设计(递归下降法、输出三地址表示)初始条件:理论:学完编译课程,掌握一种计算机高级语言的使用。
实践:计算机实验室提供计算机及软件环境。
如果自己有计算机可以在其上进行设计。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)(1)写出符合给定的语法分析方法的文法及属性文法。
(2)完成题目要求的中间代码三地址表示的描述。
(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。
(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
(5)设计报告格式按附件要求书写。
课程设计报告书正文的内容应包括:1 系统描述(问题域描述);2 文法及属性文法的描述;3 语法分析方法描述及语法分析表设计;4 按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;5 编译系统的概要设计;6 详细的算法描述(流程图或伪代码);7 软件的测试方法和测试结果;8 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);9 参考文献(按公开发表的规范书写)。
时间安排:设计安排一周:周1、周2:完成系统分析及设计。
周3、周4:完成程序调试及测试。
周5:撰写课程设计报告。
设计验收安排:设计周的星期五第1节课开始到实验室进行上机验收。
设计报告书收取时间:设计周的次周星期一上午10点。
指导教师签名: 2010年 11月 23日系主任(或责任教师)签名: 2010年 11月 23日WHILE循环语句的翻译程序设计(递归下降法、输出三地址表示)1任务使用C++语言编写一个while循环语句的翻译程序,使用递归下降法进行语法分析,输出三地址码表示。
程序流程控制——Do While语句Do While也是循环语句,它分为两种情况,一种是把循环条件放在开头,一种是把循环条件放在结尾。
1、开头判断循环条件语句格式:Do Wihle 循环条件语句块1[Exit Do]语句块2Loop首先判断循环条件,条件为真则执行Do到Loop之间的语句。
2、结尾判断循环条件语句格式:Do语句块1[Exit Do]语句块2Loop Wihle 循环条件先执行一次Do到Loop 之间的语句,再判断循环条件,满足条件则进行循环。
两种格式的区别:因为第二种格式是把循环体放在尾部,得先执行一遍语句再进行循环条件判断,所以,同样的条件,第二种格式的循环会比第一种多执行一次循环部份的语句。
我们用Do While语句来解决求1——1000的自然数的和的问题:Sub mysum()Dim Lsum As Long, i As Longi = 1Do While i <= 1000Lsum = Lsum ii = i 1LoopMsgBox '1到1000的自然数和为:' & LsumEnd Sub程序流程控制——Do Until 语句这个和Do While语句类似,它也有两种形式,学了Do While语句,再看这个,就可以无师自通了。
下面就简单介绍下:1、开头判断循环条件语句格式:Do Until 循环条件语句块1[Exit Do]语句块2Loop2、结尾判断循环条件语句格式:Do语句块1[Exit Do]语句块2Loop Until 循环条件执行Do 和Loop之间的指令,直到循环条件为真时退出循环。
直到循环条件为真时退出循环,这是Do Until与Do While的区别。
而它两种语句格式的区别,也是第二种比第一种多执行一次循环部分的语句。
还是求1——1000自然数的问题,这次我们换用Do Untile 语句:Sub mysum()Dim Lsum As Long, i As Longi = 1DoLsum = Lsum ii = i 1Loop Until i > 1000MsgBox '1到1000的自然数和为:' & LsumEnd Sub程序流程控制——Go to 语句Go to 在英语里是什么?相信大家的英语都比我好得太多,不用多说。
dowhile语句实践运用do-while语句是一种循环结构,它先执行一次循环体,然后再根据条件判断是否继续执行循环。
接下来,我将以人类的视角,用准确的中文描述,给你展示几个do-while语句的实践运用场景。
一、购物结算小明去超市购物,他买了苹果、香蕉和橙子。
他需要使用do-while 语句来实现购物结算的功能。
首先,他将购买的商品放入购物车,然后计算购物车中商品的总价。
接着,他询问是否继续购买,如果是,则继续添加商品到购物车,否则结束购物并输出购物车中商品的总价。
二、学生成绩统计某班级有10名学生,老师需要使用do-while语句来统计学生的成绩。
老师首先输入学生的姓名和成绩,然后判断是否还有其他学生需要输入成绩。
如果是,则继续输入下一位学生的成绩,否则结束输入并计算学生的平均成绩和最高分。
三、密码验证某应用程序需要使用do-while语句来验证用户的密码。
用户需要输入密码,然后程序判断密码是否正确。
如果密码不正确,则提示用户重新输入密码,直到输入正确的密码为止。
四、游戏猜数小明和小红在玩一个猜数字的游戏。
小红想一个数字,小明需要猜这个数字是多少。
小明每次猜完后,小红会告诉他猜的数字是大了还是小了。
小明使用do-while语句来循环猜数字,直到猜中为止。
五、倒计时某个倒计时程序需要使用do-while语句来实现倒计时功能。
程序首先设置倒计时的时间,然后开始倒计时。
在每次倒计时结束后,程序判断是否还需要继续倒计时。
如果是,则继续倒计时,否则结束倒计时。
六、跳绳计数小明正在练习跳绳,他使用do-while语句来记录他跳绳的次数。
每次跳绳后,他会询问自己是否还要继续跳绳。
如果是,则继续跳绳并增加跳绳次数,否则结束跳绳并输出跳绳的总次数。
七、旅行计划小红正在计划一个旅行,她使用do-while语句来帮助她安排旅行的行程。
首先,她选择旅行的目的地和出发日期。
然后,她询问自己是否还要添加其他目的地。
如果是,则继续添加目的地和出发日期,否则结束计划并输出旅行的行程安排。
附件1:学号:0120910340525课程设计题目DO-WHILE(简单优先法、输出三地址表示)学院计算机科学与技术专业计算机科学与技术班级0905姓名明正超指导教师杨克俭2012 年 1 月 3 日课程设计任务书学生姓名:明正超专业班级:计算机0905班指导教师:杨克俭工作单位:计算机科学与技术学院题目: DO-WHILE循环语句的翻译程序设计(简单优先法、输出三地址表示)初始条件:理论:学完编译课程,掌握一种计算机高级语言的使用。
实践:计算机实验室提供计算机及软件环境。
如果自己有计算机可以在其上进行设计。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)(1)写出符合给定的语法分析方法的文法及属性文法。
(2)完成题目要求的中间代码三地址表示的描述。
(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。
(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
(5)设计报告格式按附件要求书写。
课程设计报告书正文的内容应包括:1 系统描述(问题域描述);2 文法及属性文法的描述;3 语法分析方法描述及语法分析表设计;4 按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;5 编译系统的概要设计;6 详细的算法描述(流程图或伪代码);7 软件的测试方法和测试结果;8 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);9 参考文献(按公开发表的规范书写)。
时间安排:设计安排一周:周1、周2:完成系统分析及设计。
周3、周4:完成程序调试及测试。
周5:撰写课程设计报告。
设计验收安排:设计周的星期五第1节课开始到实验室进行上机验收。
设计报告书收取时间:设计周的次周星期一上午10点。
指导教师签名: 2011年 11月23日系主任(或责任教师)签名: 2011年 11月 23日(一)系统描述根据所学编译原理有关词法分析,语法分析,语义分析有关规则,对DO_WHILE循环语句的翻译程序进行设计,使用高级语言或者伪代码形式,进行编写,其中要求使用简单优先法法并在程序的最终结果中显示出表达式的三地址形式。
do while循环语句用法
嘿,朋友们!咱今儿个就来好好唠唠 do while 循环语句的用法。
你想啊,就好比你去跑马拉松,do while 循环就像是你先不管三七
二十一地跑起来,然后在特定条件下才决定是不是继续跑。
比如说,
你设定一个目标,“只要我还没跑到终点,我就继续跑”,这就是 do while 循环的精髓所在!
咱先说说它的基本结构哈。
“do”后面紧跟着要执行的代码块,然后
是“while”,再加上判断条件。
这就像是一个有决心的人,先行动起来,然后再看看情况决定下一步。
比如说,你让程序一直输出数字,直到某个数字出现。
这就像你在
玩猜数字游戏,一直猜,直到猜对了为止!“哎呀,我怎么还没猜对呀!”这时候 do while 循环就派上用场啦。
再举个例子,你想让程序不断地接收用户输入,直到用户输入一个
特定的字符。
这多有意思呀,就像你和朋友聊天,一直聊到说到某个
关键词为止。
“嘿,你怎么还不说那个词呀!”
它和其他循环语句比起来,有它独特的优势呢。
它至少会执行一次
代码块,这就好比你下定决心要做一件事,不管怎样先做了再说。
不
像有些循环,可能因为条件不满足一开始就不执行。
总之,do while 循环语句就像是一个勇往直前的战士,先冲出去再说!它在很多情况下都超级实用,能帮我们解决好多问题呢。
我觉得 do while 循环语句真是编程世界里不可或缺的一部分呀,它能让我们的程序更灵活、更有趣!你们觉得呢?。
do while语句的用法c语言
do-while语句可以表示一段循环语句。
它先执行循环体内的代码,然后再测试循环控制条件是否满足。
只有当循环控制条件不满足时,才结束循环。
其基本语法如下:
c
do {
循环体语句
}while(循环控制条件);
其中,循环体语句是要重复执行的语句,循环控制条件是一组判断语句,它决定循环是否继续执行。
具体用法可见下面的例子:
c
#include <stdio.h>
int main()
{
int i = 0;
do {
printf("i = %d\n", i);
i++;
}while(i < 5);
return 0;
}
执行结果:
i = 0
i = 1
i = 2
i = 3
i = 4
这个例子中,循环体包含了一个输出语句和一个自增语句,而循环控制条件是判
断i 是否小于5。
循环会一直执行,直到i 的值达到5,才会停止循环。
DO-WHILE循环语句翻译程序的设计目录第一章概述 (1)1.1 课程设计背景 (1)1.2 课程设计目的 (1)1.3 实验环境与开发工具 (1)1.4 C++语言简单介绍 (2)第二章设计内容 (3)2.1 设计需求陈述 (3)2.1.1词法分析的原理 (4)2.1.2 语法分析器的原理 (5)2.1.3 语义分析中间代码生成器的原理.......................................... 错误!未定义书签。
2.2 需要完成的功能................................................................................. 错误!未定义书签。
2.2.1 判定输入的文法词法分析是否正确 (8)2.2.2 判定输入的文法语法分析是否正确 (9)2.2.3中间代码(四元式)的生成与输出 (10)2.3 分析器的构造 (11)第三章逻辑设计 (12)3.1系统的组织与基本工作流程 (12)3.2 总体结构逻辑结构图 (13)第四章详细设计.............................................................................................. 错误!未定义书签。
4.1 软件功能分析................................................................................... 错误!未定义书签。
4.1.1 判定输入文法词法分析是否正确 (14)4.1.2 判定输入的文法的语法分析是否正确.................................. 错误!未定义书签。
4.1.3 语义分析和中间代码生成...................................................... 错误!未定义书签。
目录1 问题域描述 (3)2 文法及属性文法的描述 (3)2.1 WHILE循环语句的文法 (3)2.2 WHILE循环语句的属性文法 (4)3 语法分析方法及中间代码形式的描述 (4)3.1语法分析方法 (4)3.2中间代码形式描述 (6)4 编译系统的概要设计 (7)4.1词法分析 (7)4.2语法制导翻译 (8)5 详细的算法描述 (8)5.1 文法设计 (8)5.2 算法描述 (8)5.3 源程序代码 (9)6 软件的调试过程和结果测试 (19)6.1调试过程 (19)6.2结果测试 (19)7 使用说明 (20)8 课设总结 (20)9 参考文献 (22)WHILE循环语句的翻译程序设计(简单优先法、输出三地址表示)1 问题域描述while循环语句的翻译程序设计(简单优先法,输出单地址表示),要求完成:(1)用C++语言正确编写程序,完成WHILE循环语句的翻译程序设计。
(2)求能正确进行词法分析,语法分析,并能正确的输出预期结果。
(3)根据指定的文法,判定程序的正确性。
本次课程设计中要求设计一个WHILE循环语句的词法﹑语法及语义分析程序,语法分析选择简单优先法,采用语法制导翻译输出中间代码三元式。
通过设计、编制、调试一个WHILE循环语句的语法及语义分析程序,加深对语法及语义分析原理的理解,实现功能。
while循环语句的格式为:while(P){do A},其中A为循环体,可为一个或多个赋值语句;P为循环控制条件。
while循环语句首先根据循环控制条件P进行判断,若满足条件则执行循环体A,否则执行下面的程序段;本次课程设计中系统首先要进行词法分析,即从左到右把源文件的字符序列逐个进行扫描,产生一个个的单词序列,作为语法分析的输入从而继续编译过程。
该程序的语法分析读入词法分析的结果,并判断输入语句是否满足while循环语句的文法所描述的形式。
通过简单优先法对语句进行分析,看是否能通过给定的输入串归约到文法的开始符号。
7.2.2 循环结构程序设计1、DO WHILE-ENDDO语句语句格式:DO WHILE <条件表达式><语句序列1>[LOOP]<语句序列2>[EXIT]ENDDO语句功能:当条件表达式的值为真时,始终执行语句组;否则执行ENDDO后面的语句。
例如:以显示方式输出1-10的数字。
SET TALK OFFCLEARI=1DO WHILE I <=10? II=I+1ENDDO语句I=I+1就是用来修改循环条件的,如果没有这一句,I的值永远等于是,上述循环就成为一个死循环。
例如:在双重循环中,LOOP语句在内循环体中,当执行到LOOP语句时,它跳回到内循环的DO WHILE的开始处,重复对<条件表达式2>的判断。
DO WHILE <条件表达式1>…DO WHILE <条件表达式2>…LOOP…ENDDO…ENDDO例如:将DA1.DBF表中凡是工资小于700元的增加100元。
SET TALK OFFUSE DA2DO WHILE .NOT.EOF()IF 工资>=700SKIPLOOPENDIFREPLACE 工资 WITH 工资+100SKIPENDDOSET TALK ONRETURN2、FOR-ENDFOR语句该语句通常用于实现循环次数已知情况下的循环结构。
语句格式:FOR 循环变量=<初值>TO<终值>[STEP<步长>]<命令序列>[LOOP][EXIT]ENDFOR语句功能:执行该语句时,首先将初值赋给循环变量,然后判断条件是否成立(若步长为正值,循环条件为<循环变量><=<终值>;若步长为负值,循环条件为<循环变量> >=<终值>)。
若循环条件成立,则执行循环体,每当执行一次循环,循环变量增加一个步长值,并再次判断条件是否成立。
dowhile语句的用法
do-while语句是一种循环结构,它会先执行循环体内的代码,然后再检查循环条件。
只有当循环条件为真时,才会继续执行下一次循环。
do-while语句的用法如下:
```
do
//循环体的代码
} while (循环条件);
```
具体解释如下:
1.执行循环体的代码。
2.检查循环条件。
如果条件为真,继续执行下一次循环;如果条件为假,退出循环。
3.重复步骤1和2,直到条件为假。
与其他循环结构(如for和while)不同的是,do-while语句保证循环体中的代码至少会执行一次,即使循环条件一开始就为假。
这是因为循环条件是在循环体执行完之后才被检查的。
do-while语句通常用于需要至少执行一次循环体的情况,例如用户输入验证和菜单选择等。
dowhile循环语句
嘿,朋友!你知道那个超厉害的 do while 循环语句吗?就好像是一
个不知疲倦的小勇士,一直在战斗呢!比如说,你想让程序先执行一
段代码,然后再根据条件判断是否继续循环,这时候 do while 就派上
大用场啦!
想象一下,你在玩一个游戏,你必须先迈出第一步,然后看看情况
再决定要不要继续走下去,这和 do while 循环多像呀!你先执行一次
代码,然后再去检查条件。
“哎呀,条件满足,那就再来一次呗!”它
就是这么直接,这么干脆!
我记得有一次,我在写一个程序,要计算一些数据的累计和。
我一
开始用了其他的循环语句,结果总是不太对。
后来我突然想到了 do while,一试,哇塞,简直完美!就像找到了一把神奇的钥匙,一下子
就打开了那扇困住我的门。
在编程的世界里,do while 循环语句就像是一个可靠的伙伴。
它不
会轻易放弃,一直陪着你解决问题。
它不会问你“行不行呀”“能不能呀”,而是直接就上,“先干了再说!”这种勇往直前的精神,真的让人佩服。
你看,其他的循环语句可能会先看看条件再决定要不要行动,do while 可不一样,它就是这么有个性!它就像一个勇敢的探险家,不管
前面有什么,先冲进去再说。
总之,do while 循环语句就是那么独特,那么不可或缺。
它在编程中有着重要的地位,能帮我们解决好多难题呢!你难道不想去试试,感受一下它的魅力吗?。
课程设计任务书学生姓名:专业班级:指导教师:工作单位:计算机科学与技术学院题目: DO-WHILE循环语句的翻译程序设计(LL(1)法、输出三地址表示)初始条件:理论:学完编译课程,掌握一种计算机高级语言的使用。
实践:计算机实验室提供计算机及软件环境。
如果自己有计算机可以在其上进行设计。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)(1)写出符合给定的语法分析方法的文法及属性文法。
(2)完成题目要求的中间代码三地址表示的描述。
(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。
(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
(5)设计报告格式按附件要求书写。
课程设计报告书正文的内容应包括:1 系统描述(问题域描述);2 文法及属性文法的描述;3 语法分析方法描述及语法分析表设计;4 按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;5 编译系统的概要设计;6 详细的算法描述(流程图或伪代码);7 软件的测试方法和测试结果;8 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);9 参考文献(按公开发表的规范书写)。
时间安排:设计安排一周:周1、周2:完成系统分析及设计。
周3、周4:完成程序调试及测试。
周5:撰写课程设计报告。
设计验收安排:设计周的星期五第1节课开始到实验室进行上机验收。
设计报告书收取时间:设计周的次周星期一上午10点。
指导教师签名: 2011年月日系主任(或责任教师)签名: 2011年月日DO-WHILE循环语句的翻译程序设计(LL(1)法、输出三地址表示)1. 系统描述1.1 设计目的通过设计、编制、调试一个DO-WHILE循环语句的语法及语义分析程序,加深对法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。
1.2 设计内容及步骤对循环语句: DO〈赋值语句〉WHILE 〈表达式〉(1)按给定的题目写出符合自身语法分析方法要求的文法和属性文法描述。
(2)按给定的题目给出语法分析方法的思想及分析表设计。
(3)按给定的题目给出中间代码序列的结构设计。
(4)完成相应的词法分析、语法分析和语义分析程序设计。
(5)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
2. 文法及属性文法的描述2.1 文法描述K -> do L while S L -> SPP -> ;SP | εS -> iQEE -> TG G -> +TG | -TG | εT -> FRR -> *FR | /FR | εF -> (E) | iQ -> = | < | >2.2 属性文法的描述3. 语法分析方法描述及语法分析表设计3.1 语法分析方法的描述确定的自顶向下分析方法,是从文法的开始符号出发,考虑如何根据当前输入符号(单词符号)唯一地确定选用哪个产生式替换相应非终结符以往下推导,或构造一棵相应的语法树。
由分析可知,能够使用自顶向下分析技术的文法正是LL(1)文法。
LL(1)的含义是:第1个L表明自顶向下分析是从左到右扫描输入串,第2个L表明分析过程中将用最左推导,1表明只需向右看一个符号便可决定如何推导即选择哪个产生式(规则)进行推导。
一个上下无关文法是LL(1)文法的充分必要条件是,对每个非终结符A的任意两个不同的产生式,A→α,A→β,均满足:SEKECT(A→α)∩SEKECT(A→β)=Ф,其中α、β不能同时推导出ε。
当我们需要选用自顶向下分析技术时,首先必须判别所给文法是否是LL(1)文法。
因而对任给文法需计算FIRST、FOLLOW、SELECT集合,进而判别文法是否为LL(1)文法。
对判断确定的LL(1)文法,构造预测分析表。
分析表可以用一个矩阵M(或称二维数组)表示。
矩阵的元素M[A,a]中的下标A表示非终结符,a为终结符或句子括号“#”,矩阵元素M[A,a]中的内容是一条关于A的产生式,表明当用终结符A向下推导时,面临输入符号a时,所应采取的候选产生式,当元素内容无产生式时,则表明用A为左部向下推导时遇到了不该出现的符号,因此元素内容为转向出错处理的信息。
3.2 语法分析表的设计3.2.1 各非终结符的FIRST集合:FIRST(K)={ do }FIRST(L)={ i }FIRST(S)={ i }FIRST(P)={ ; , ε } FIRST(Q)={ = , < , > } FIRST(E)={ ( , i } FIRST(T)={ ( , i } FIRST(G)={ - , + , ε } FIRST(F)={ ( , i } FIRST(R)={ * , / , ε }3.2.2 各非终结符的FOLLOW集合:FOLLOW(L)={ w } FOLLOW(S)={ ; , w , # } FOLLOW(P)={ w } FOLLOW(Q)={ ( , i } FOLLOW(E)={ ) , w , # } FOLLOW(T)={ + ,- ,w }FOLLOW(G)={ ; , w , ) , # } FOLLOW(F)={ * , / , ) , w ,# } FOLLOW(R)={ ) , w , ; , + ,- , # }3.2.3 各产生式的SELECT集合:SELECT(K->do L while S)={ do } SELECT(L->SP)={ i }SELECT(P->;SP)={ ; }SELECT(P->ε)={ w }SELECT(S->iQE)={ i }SELECT(E->TG)={ ( , i } SELECT(G->+TG)={ + }SELECT(G->-TG)={ - }SELECT(G->ε)={ ; , w , - , # } SELECT(T->FR)={ I , ( }SELECT(R->*FR)={ * }SELECT(R->/FR)={ / }SELECT(R->ε)={ ) , w , + , - , ; , # } SELECT(F->(E))={ ( }SELECT(F->i)={ i }SELECT(Q->=)={ = }SELECT(Q-><)={ < }SELECT(Q->>)={ > }由上可知有相同左部产生式的SELECT集合的交集为空,所以文法是LL(1)文法。
3.3.4 构造预测分析表:注:表中用d代表do,w代表while。
4. 三地址表示的描述及其结构设计4.1三地址描述此课程设计要求中间代码使用三地址表示,三地址码是由下面一般形式的语句构成的序列: x := y op z其中,x y z为名字、常数或临时变量;op代表运算符号。
每个语句中只能有一个运算符。
本程序中使用的三地址语句有:赋值语句 x := y op z , x :=op y , x := y条件转移语句if x relop y goto L //L为带标号L的三地址语句4.2 三地址结构设计对于形如:do{ 算术表达式1:x=y+z ;算术表达式2:p=m*n ;……} while(逻辑表达式:j<i)翻译成如下形式:L0:L1 = y+zx = L1L2 = m*np = L2……Ln = j<iif Ln goto L0if not goto Ln+1Ln+1:5. 编译系统的设计及算法为实现do-while语句的词法分析、语法分析和语义分析的程序设计,我们进行了如下系统设计:5.1 文法存储定义字符数组VN[]、VT[]、P[][]和整型数组M[][]。
VN[]存放文法中的所有非终结符,并以‘\0’结束;VT[]存放文法中的所有终结符,并以‘\0’结束;P[][]按一定的顺序存放文法产生式右部;M[][]是二维数组,存放的是预测分析表,行对应终结符A在VN[]中的位置,列对应非终结符在VT[]中的位置,数组中的非负元素相应对应文法产生式右部在P[][]中的位置,负数表示出错标志。
对输入的字符序列进行处理,将输入字符序列中的空字符去掉,将处理后的字符依次存放在字符数组var[]中,并以‘\0’结束。
5.2 词法分析void lexical(){for(i=0;var[i]!='#';i++){ch=var[i];if(ch=='d'&&var[i+1]=='o') /* 若遇到字符‘d’,则判断下一个字符是否是‘o’:若是,则为关键字‘do’,用‘d’表示存放在队列中;否则,进行其他操作*/ {词法分析识别,字符进入队列;}else if(ch=='w'){对后续字符进行扫描,判断其是否是关键字‘while’序列若是,则进行词法分析识别,字符进入队列;否则,返回;}else if(index(ch,VT)<=0) //判断ch是否是界符或标识符{if(ch!=界符){词法分析识别,保存输入字符,字符进入队列;}else 词法分析识别;}else if(index(ch,VT)>0) //判断是否是除标识符以外的终结符{词法分析识别,字符进入队列;}}}5.3 语法分析图中符号说明如下:“#”句子括号即输入串的括号“S”文法的开始符号“X”存放当前栈顶符号的工作单元“a”存放当前输入符号a的工作单元void syntax(){规约过程,打印栈和队列;X=stack[sp];a=queue[front];if(X=='#'&&a=='#') 规约成功;if(X是终结符){if(X==a){sp--; front++;if(a!='i'){if(a!='d'&&a!='w'&&a!=';'&&a!='#') opr=index(a,VT);else if(a==';'||a=='w'||a=='#') opr=-2;cout<<'\t'<<'\''<<a<<"'匹配"<<endl;}else 输出标识符,匹配成功;}else 字符不匹配,转去出错处理;}else {int tx=index(X,VN);int ta=index(a,VT);n=M[tx][ta];td[t++]=M[tx][ta];if(ta==-1)字符没有出现在产生式终结符集VT中,转去出错处理;else if(n==-1) 没有找到合适的候选产生式来做进一步推导,转去出错处理;else { 用产生式M[tx][ta]来做进一步推导for(int i=len(p[n])-1;i>=0;i--){stack[++sp]=p[n][i];cout<<p[n][len(p[n])-1-i];}}}if(f==0) syntax();else 出错处理;}5.4 语义分析void semantic(){while(var[j]!='\0'){if(var[j]=='='){赋值语句依次存放在arr[d][k]中;d++; j--;}if(var[j]=='<'||var[j]=='>'){条件表达式存放在数组arr[d][k]最后;j--;}j++;}}void semantic_out() //输出三地址{int k=0,i,j;cout<<"L"<<k<<":"<<endl;k++;for(i=0;i<d-1;i++){中间变量=赋值语句右部;赋值语句左部=中间变量;}cout<<"L"<<k<<"=";for(j=0;arr[i][j]!='\0';j++) //输出条件表达式cout<<arr[i][j];cout<<endl;cout<<"if L"<<k<<" goto L0"<<endl;k++;cout<<"if not goto L"<<k<<endl;cout<<"L"<<k<<":"<<endl;}6 源程序和结果6.1 源程序#include<iostream.h>#define MAX 100char X,a;char VN[11]={'K','L','P','S','E','G','T','R','F','Q','\0'};char VT[15]={'i','=','<','>','+','-','*','/','(',')','d','w',';','#','\0'}; charp[18][6]={"dLwS\0","SP\0",";SP\0","\0","iQE\0","TG\0","+TG\0","-TG\0","\0","F R\0","*FR\0","/FR\0","\0","(E)\0","i\0","=\0","<\0",">\0"};char stack[MAX];char queue[MAX];int sp,front;int M[10][14]={ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1},{ 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 3, 2,-1},{ 4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},{ 5,-1,-1,-1,-1,-1,-1,-1, 5,-1,-1,-1,-1,-1},{-1,-1,-1,-1, 6, 7,-1,-1,-1, 8,-1, 8, 8, 8},{ 9,-1,-1,-1,-1,-1,-1,-1, 9,-1,-1,-1,-1,-1},{-1,-1,-1,-1,12,12,10,11,-1,12,-1,12,12,12},{14,-1,-1,-1,-1,-1,-1,-1,13,-1,-1,-1,-1,-1},{-1,15,16,17,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, };int f=0;int count=0;int c=0;char arr_i[MAX];char var[MAX];int td[MAX]; //输出产生式序列int t=0;int opd=-1;int opr=-1;int id=0;int d=0;char arr[MAX][10];//存放待输出的三地址int len(char str[]){int i=0;while(str[i]!='\0')i++;return i;}int index(char ch,char str[]){int i=0;while(str[i]!='\0'){if(ch!=str[i])i++;else break;}if(str[i]=='\0')return -1;return i;}void err(int n){if(n==1)cout<<"字符不匹配"<<endl;else if(n==2)cout<<"字符没有出现在产生式终结符集VT中"<<endl;else if(n==3)cout<<"没有找到合适的候选产生式来做进一步推导"<<endl;elsecout<<"该句子是文法语言的句子!"<<endl;}void print(){cout<<"(";if(count<10)cout<<'0';cout<<count<<")";int i;for(i=0;i<=sp;i++)cout<<stack[i];for(;i<=20;i++)cout<<" ";for(i=0;i<front;i++)cout<<" ";for(;queue[i]!='#';i++)cout<<queue[i];cout<<queue[i];for(;i<=20;i++)cout<<" ";}void semantic(){int j=0,k;while(var[j]!='\0'){if(var[j]=='='){k=0;for(j=j-1;(var[j]!=';')&&(var[j]!='}');j++,k++){arr[d][k]=var[j];}arr[d][k]='\0';d++;j--;}if(var[j]=='<'||var[j]=='>'){k=0;for(j=j-1;var[j]!='}';j++,k++)arr[d][k]=var[j];arr[d][k]='\0';d++;j--;}j++;}}void semantic_out(){int k=0,i,j;cout<<"L"<<k<<":"<<endl;k++;for(i=0;i<d-1;i++){cout<<"L"<<k<<"=";for(j=2;arr[i][j]!='\0';j++){cout<<arr[i][j]<<" ";}cout<<endl;cout<<arr[i][0]<<"="<<"L"<<k<<endl;k++;}cout<<"L"<<k<<"=";for(j=0;arr[i][j]!='\0';j++){cout<<arr[i][j];}cout<<endl;cout<<"if L"<<k<<" goto L0"<<endl;k++;cout<<"if not goto L"<<k<<endl;cout<<"L"<<k<<":"<<endl;}void syntax(){int n;count++;print();X=stack[sp];a=queue[front];if(X=='#'&&a=='#')f=4;if(X<'A'||X>'Z'){if(X==a){sp--;front++;if(a!='i'){if(a!='d'&&a!='w'&&a!=';'&&a!='#'){opr=index(a,VT);}else if(a==';'||a=='w'||a=='#'){opr=-2;}cout<<'\t'<<'\''<<a<<"'匹配"<<endl;}else{opd=c;cout<<'\t'<<'\''<<arr_i[c++]<<"'匹配"<<endl;}}else f=1; //字符不匹配,转去出错处理}else{int tx=index(X,VN);int ta=index(a,VT);n=M[tx][ta];td[t++]=M[tx][ta];if(ta==-1){f=2;cout<<a<<endl;} //字符没有出现在产生式终结符集VT中,转去出错处理else if(n==-1)f=3; //没有找到合适的候选产生式来做进一步推导,转去出错处理else{ //用产生式M[tx][ta]来做进一步推导sp--;cout<<'\t'<<X<<"->";if(len(p[n])!=0){for(int i=len(p[n])-1;i>=0;i--){stack[++sp]=p[n][i];cout<<p[n][len(p[n])-1-i];}cout<<endl;}else cout<<"空串"<<endl;}}if(f==0)syntax();else{td[t]='-1';err(f);}}void lexical(){ //do{m=m+i;i=i+1;}while(i<4);#int i,j,d;char ch;j=d=0;for(i=0;var[i]!='#';i++){ch=var[i];if(ch=='d'&&var[i+1]=='o'){cout<<"do"<<'\t'<<"keyword"<<endl;queue[j++]='d';i+=1;}else if(ch=='w'){ch=var[i+1];if(ch=='h'){ch=var[i+2];if(ch=='i'){ch=var[i+3];if(ch=='l'){ch=var[i+4];if(ch=='e'){ch=var[i+5];}}}}cout<<"while"<<'\t'<<"keyword"<<endl;queue[j++]='w';i+=4;}else if(index(ch,VT)<=0){if(ch!='{'&&ch!='}'&&ch!='('&&ch!=')'){cout<<ch<<'\t'<<"variable:i["<<d++<<"]"<<endl;arr_i[d-1]=ch;queue[j++]='i';}else cout<<ch<<'\t'<<"bound"<<endl;}else if(index(ch,VT)>0){cout<<ch<<'\t'<<"operator"<<endl;queue[j++]=ch;}}queue[j]='#';for(i=0;queue[i]!='#';i++)cout<<queue[i];cout<<endl;}int main(){int i=0;char S='K';sp=front=0;stack[0]='#';sp++;stack[1]='K';cout<<"LL(1)文法如下:"<<endl;cout<<"(0)K->dLwS\n(1)L->SP\n(2)P->;SP\n(3)P->ε\n(4)S->iQE\n(5)E->TG\n(6) G->+TG\n"<<"(7)G->-TG\n(8)G->ε\n(9)T->FR\n(10)R->*FR\n(11)R->/FR\n(12)R->ε\ n(13)F->(E)\n"<<"(14)F->i\n(15)Q->=\n(16)Q-><\n(17)Q->>\n";cout<<"请输入do-while语句:";do{cin>>var[i];i++;if(var[i]==' ')i--;}while(var[i-1]!='#');var[i]='\0';cout<<"词法分析:"<<endl;lexical();cout<<"LL(1)语法分析:"<<endl;syntax();cout<<"所用产生式序列:"<<endl;for(i=0;td[i]!='-1';i++)cout<<td[i]<<" ";cout<<endl;cout<<"输出三地址:"<<endl;semantic();semantic_out();return 0;}文法.txt/*文法:(0)K->dLwS(1)L->SP(2)P->;SP(3)P->ε(4)S->iQE(5)E->TG(6)G->+TG(7)G->-TG(8)G->ε(9)T->FR(10)R->*FR(11)R->/FR(12)R->ε(13)F->(E)(14)F->i(15)Q->=(16)Q-><(17)Q->>*//*文法:K->DLWSL->SPP->;SPP->εD->doW->while*//*输入串: do{m=m+i;i=i+1}while{i<4}#产生式: P[i][j]非终结符: VN[i]终结符: VT[i]开始符: K栈顶: X队首: a预测分析表: M[X,a] //-1表示没有,否则表示产生式序号i;且应该有P[i][0]==X*/6.2 软件的测试方法和测试结果测试用例:词法分析结果:语法分析结果:注:由于分析过程太长,这里直接取其中一部分分析过程。