一、实验目的:
利用C语言编制递归下降分析程序,并对简单语言进行语法分析。
编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
二、实验原理
每个非终结符都对应一个子程序。
该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端:
- 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理
- 每遇到一个非终结符,则调用相应的子程序
三、实验要求说明
输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。
例如:
输入begin a:=9;x:=2*3;b:=a+x end #
输出success
输入x:=a+b*c end #
输出‘end' error
四、实验步骤
1.待分析的语言的语法(参考P90)
2.将其改为文法表示,至少包含
–语句
–条件
–表达式
3. 消除其左递归
4. 提取公共左因子
5. SELECT集计算
6. LL(1)文法判断
7. 递归下降分析程序
解:
#include<stdio.h>
#include <iostream>
#include<string.h>
using namespace std;
char *reserved[6] = {"begin","if","then","while","do","end"};
char input[80],output[8];
char ch;
int syn,p,i;//syn为种别码,p为扫描与添加
int m = 0,n,row,sum = 0,count=0;
int flag = 0;//标志位
void ParseS();//解析语句
void ParseS1();
void ParseS2();
void ParseS3();
void ParseS4();
void ParseC();//解析条件
void ParseE();//解析表达式
void ParseE1();
void ParseT();//解析项
void ParseT1();
void ParseF();//解析因子
void scanner(){
for( i = 0 ; i < 8 ; i++ ){
output[i] = NULL;
}//初始化输出
ch = input[p++];
while( ch == ' ' ){
ch = input[p] ;
p ++ ;
}
//持续读入
if( ( ch >= 'a' && ch <= 'z' ) || ( ch >= 'A' && ch <= 'Z' ) ){
m = 0 ;
while( ( ch >= 'a' && ch <= 'z' ) || ( ch >= 'A' && ch <= 'Z' ) || ( ch >= '0' && ch <= '9' ) ){
output[m++] = ch ;
ch = input[p++];
}
output[m++] = '\0';
p -- ;
syn = 10 ;
for( n = 0 ; n < 6 ; n ++ ){
if( strcmp(output,reserved[n]) == 0 ){
syn = n + 1;
break;
}
}
}else if( ( ch >= '0' && ch <= '9' ) ){
sum = 0 ;
while( ch >= '0' && ch <= '9' ){
sum=sum*10+ch-'0' ;
ch = input[p++] ;
}
p -- ;
syn = 11;
}
else if(ch == '/'){
ch = input[p++] ;
if(ch == '/'){
while(ch != '\n'){
ch = input[p++] ;
}
scanner();
}
else if(ch == '*'){
ch = input[p++];
int flag=0;
// printf("%c %c",ch,input[p]);
while((ch == '*' && input[p] != '/')||(ch != '*' && input[p] == '/') || (ch != '*' && input[p] != '/')){
ch = input[p++] ;
if(p==count-2 && (ch != '*' && input[p] != '/')){
flag =1;
syn = 100;
break;
}
}
p++;
if(flag==0){
scanner();
}
}else{
p = p - 2 ;
ch = input[p++] ;
output[0] = ch ;
syn = 16 ;
}
}else switch(ch){
case '+':
output[0] = ch ;
syn = 13;
break;
case '-':
output[0] = ch ;
syn = 14;
break;
case '*':
output[0] = ch ;
syn = 15 ;
break;
case '/':
output[0] = ch ;
syn = 16 ;
break;
case ':':
i = 0;
output[i++] = ch ;
ch = input[p++];
if( ch == '=' ){
output[i++] = ch;
syn = 18 ;
}else{
syn = 17;
p-- ;
}
break;
case '<':
i = 0 ;
output[i++] = ch ;
ch = input[p++] ;
if( ch == '=' ){
output[i++] = ch ;
syn = 21 ;
}else if( ch == '>' ){
output[i++] = ch ;
syn = 22 ;
}else{
syn = 20 ;
p-- ;
}
break;
case '>':
i = 0;
output[i++] = ch ;
ch = input[p++] ;
if( ch == '=' ){
output[i++] = ch;
syn=24;
}else{
syn=23;
p--;
}
break;
case '=':
output[0] = ch ;
syn = 25 ;
break;
case ';':
output[0] = ch ;
syn = 26 ;
break;
case '(':
output[0] = ch ;
syn = 27 ;
break;
case ')':
output[0] = ch ;
syn = 28 ;
break;
case '#':
output[0] = ch ;
syn = 0;
break;
case '\n':
syn = 99 ;
break;
default:
syn = -1 ;
break;
}
}
void ParseS(){
if(flag != 0){
if(syn == 10){ //<id>:=<表达式>
scanner();
ParseS1();
}
else if(syn == 2){ //if
scanner();
ParseS2();
}
else if(syn == 4){//while
scanner();
ParseS3();
}
else if(syn == 0){
}
else{
printf("statement syntx error S\n");
exit(0);
}
}
else{
if(syn == 1){//begin
scanner();
flag = 1;
ParseS4();
}else{
printf("error,缺少begin!\n");
exit(0);
}
}
}
void ParseS1(){
if(syn==18){
scanner();
ParseE();
}
else{
printf("statement syntx error S1\n");
exit(0);
}
}
void ParseS2(){//if
ParseC();
if(syn== 3 ){
scanner();
ParseS();
}
else{
printf("statement syntx error S2\n");
exit(0);
}
}
void ParseS3(){//while
ParseC();
if(syn== 5 ){
scanner();
ParseS();
}
else{
printf("statement syntx error S3 \n");
exit(0);
}
}
void ParseS4(){//begin
ParseS();
while(syn == 26){
scanner();
ParseS();
}
if(syn == 6){
scanner();
if(syn == 0){
printf("success!");
}
else{
printf("statement syntx error S4\n");
}
}
else{
printf("error,缺少end\n");
exit(0);
}
}
void ParseC(){
ParseE();
if(syn==25||syn==0||syn==20||syn==21||syn==23||syn==24){
scanner();
scanner();
}
else{
printf("condition syntx error C\n");
exit(0);
}
ParseE();
}
void ParseE(){
ParseT();
ParseE1();
}
void ParseE1(){
if(syn == 13 || syn == 14){
scanner();
ParseT();
ParseE1();
}
else if(syn == 28 || syn == 0){
}
}
void ParseT(){
ParseF();
ParseT1();
}
void ParseT1(){
if(syn == 15 || syn == 16){
scanner();
ParseF();
ParseT1();
}
else if(syn == 13 ||syn == 14 || syn == 28 || syn == 0){
}
}
void ParseF(){
if(syn == 27){
scanner();
ParseE();
if(syn == 28){
scanner();
}
else{
printf("factor syntx error F\n");
exit(0);
}
}
else if(syn == 10 || syn == 11){
scanner();
}
else{
printf("factor syntx error F\n");
exit(0);
}
}
int main() {
p = 0;
printf("请输入源程序:");
do{
ch = getchar();
input[p++] = ch;
}while(ch != '#');
count = p;
p = 0;
scanner();
ParseS();
return 0;
}

来源:https://www.cnblogs.com/kushoulder/p/11960161.html