Job twelve - second experiment recursive descent parser

First, the purpose of the experiment:

The use of C language compiled recursive descent parsing procedures, and simple language parsing.

The preparation of a recursive descent parser, syntax checking and realize the structure of the word lexical analysis program provided by sequence analysis.

 

Second, the experimental principle

Each nonterminal symbol corresponds to a subroutine.

This subroutine is determined according to a next input symbol (SELECT sets) which are processed in a production, then the right end of the production according to:

  • Each encounter a terminator, it is determined whether the current read word matches the terminator, if matched, then the next word is read to continue the analysis; do not match, an error process is performed
  • Each encounter a nonterminal, the appropriate subroutine is called

 

Third, the experiment asked for clarification

Enter the word string to "#" end if the grammar is correct sentences, the output success information, print "success", otherwise output "error", and pointed out grammatical errors of the type and location.

E.g:

Input begin a: = 9; x: = 2 * 3; b: = a + x end #

Output success

Input x: = a + b * c end #

Output 'end' error

 

Fourth, the experimental procedures

1. Grammar of the language to be analyzed (refer to P90)

2. Grammar to be expressed, at least comprising

- Statement

-condition

-expression

3. eliminate left recursion

4. Extract the left common factor

5. SELECT set computing

6. LL (1) grammar is determined

7. recursive descent parser

 

 

Connect to the last blog ( https://www.cnblogs.com/a131452/p/11646345.html code) improved:

#include<conio.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

char duru[100], zuche[20];
char ch;
int fg,p,m,n,num; 
char *index[35]={"begin","if","then","while","do","end","char","double","enum","float","int","long","short","signed",
"struct","union","unsigned","void","for","break","continue","else","goto","switch","case","default",
"return","auto","extern","register","static","const","sizeof","typedef","volatile"};


void E();
void T();
void E1();
void T1();
void F();
void error();

void scaner(){
for (n=0;n<20;n++)
zuche[n]=NULL;
m=0;
num=0;
ch=duru[p++];
while(ch==' '){ //跳过空格
ch=duru[p++];
}
if(ch>='a'&&ch<='z'){ //判断单词
while(ch>='a'&&ch<='z'){
zuche[m++]=ch;
ch=duru[p++];
}
fg=10;
p--;
for(n=0;n<6;n++){
if(strcmp(zuche,index[n])==0){
fg=n+1;
break;
}
}
}
else{ 
if(ch>='0'&&ch<='9'){ //判断数字
while(ch>='0'&&ch<='9'){
num=num*10+(ch-'0');
ch=duru[p++];
}
fg=11;
p--;
}
else{
switch(ch){
case '<':
zuche[m++]=ch;
ch=duru[p++];
if(ch=='>'){ //<>
fg=22;
zuche[m++]=ch;
}
else if(ch=='='){ //<=
fg=21;
zuche[m++]=ch;
}
else{ //<
fg=20;
p--;
}
break;

case '>':
m=0;
zuche[m++]=ch;
ch=duru[p++];
if(ch=='='){ //>=
fg=24;
zuche[m++]=ch;
}
else{ //>
fg=23;
p--;
}
break;

case ':':
m=0;
zuche[m++]=ch;
ch=duru[p++];
if(ch=='='){ //:=
fg=18;
zuche[m++]=ch;
}
else{ //:
fg=17;
p--;
}
break;

case '+':fg=13;zuche[0]=ch;break;
case '-':fg=14;zuche[0]=ch;break;
case '*':fg=15;zuche[0]=ch;break;
case '/':fg=16;zuche[0]=ch;break;
case '=':fg=25;zuche[0]=ch;break;
case ';':fg=26;zuche[0]=ch;break;
case '(':fg=27;zuche[0]=ch;break;
case ')':fg=28;zuche[0]=ch;break;
case '#':fg=0;zuche[0]=ch;break;
default:fg=-1;zuche[0]=ch;break;
}
}
}
}

void E(){
T();
E1();
}

void E1(){
if(fg==13){
scaner();
T();
E1();
}
else if (fg==0||fg==28){
}
else
error();
}

void T(){
F();
T1();
}

void T1(){
if(fg==15){
scaner();
F();
T1();
}
else if (fg==0||fg==28||fg==13){
}
else
error();
}

void F(){
if(fg==27){
scaner();
E();
if(fg==28)
scaner();
else
error();
}
else if (fg==11||fg==10)
scaner();
else
error();
}

error void () {
the printf ( "\ n-(% S, Error)!", zuche);
}

int main () {
P = 0;
the printf ( "Enter a symbol string (End with '#'): \ n-");
do
{
CH = getchar ();
Duru [P ++] = CH;
} the while (CH =! '#');
P = 0;
do
{
Scaner ();
E ();
}! the while (FG = 0);


getch (); // for the program to remain in the display page
}

Screenshot results:

 

 2、

#include<conio.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

char duru[100], zuche[20];
char ch;
int fg,p,m,n,num; 
char *index[35]={"begin","if","then","while","do","end","char","double","enum","float","int","long","short","signed",
"struct","union","unsigned","void","for","break","continue","else","goto","switch","case","default",
"return","auto","extern","register","static","const","sizeof","typedef","volatile"};
int kk=0; //判断是否有错误

Scaner void ();
void panduan ();
void yinzi ();
void yuju ();
void yucuan ();
void tiaojian ();
void biaoda ();
void Xiang ();


void scaner(){
for (n=0;n<20;n++)
zuche[n]=NULL;
m=0;
num=0;
ch=duru[p++];
while(ch==' '){ //跳过空格
ch=duru[p++];
}
if(ch>='a'&&ch<='z'){ //判断单词
while(ch>='a'&&ch<='z'){
zuche[m++]=ch;
ch=duru[p++];
}
fg=10;
p--;
for(n=0;n<6;n++){
if(strcmp(zuche,index[n])==0){
fg=n+1;
break;
}
}
}
else{ 
if(ch>='0'&&ch<='9'){ //判断数字
while(ch>='0'&&ch<='9'){
num=num*10+(ch-'0');
ch=duru[p++];
}
fg=11;
p--;
}
else{
switch(ch){
case '<':
zuche[m++]=ch;
ch=duru[p++];
if(ch=='>'){ //<>
fg=22;
zuche[m++]=ch;
}
else if(ch=='='){ //<=
fg=21;
zuche[m++]=ch;
}
else{ //<
fg=20;
p--;
}
break;

case '>':
m=0;
zuche[m++]=ch;
ch=duru[p++];
if(ch=='='){ //>=
fg=24;
zuche[m++]=ch;
}
else{ //>
fg=23;
p--;
}
break;

case ':':
m=0;
zuche[m++]=ch;
ch=duru[p++];
if(ch=='='){ //:=
fg=18;
zuche[m++]=ch;
}
else{ //:
fg=17;
p--;
}
break;

case '+':fg=13;zuche[0]=ch;break;
case '-':fg=14;zuche[0]=ch;break;
case '*':fg=15;zuche[0]=ch;break;
case '/':fg=16;zuche[0]=ch;break;
case '=':fg=25;zuche[0]=ch;break;
case ';':fg=26;zuche[0]=ch;break;
case '(':fg=27;zuche[0]=ch;break;
case ')':fg=28;zuche[0]=ch;break;
case '#':fg=0;zuche[0]=ch;break;
default:fg=-1;zuche[0]=ch;break;
}
}
}
}
//程序,判断是否以begin开始,end #结束
void panduan(){
if (fg==1) { //begin
scaner();
yucuan();
if (fg==6) { //end
scaner();
if (fg==0 && kk==0){
printf("success \n");
}
}
else {
printf("error,lose 'end' ! \n");
kk=1;
exit(0);
}
}
else {
printf("error,lose 'begin' ! \n");
kk=1;
exit(0);
}
return;
}
//语句串 
void yucuan() {
yuju();
while(fg==26) { 
scaner();
yuju();
}
return;
}

//语句
void yuju(){
if (fg==10) { //为标识符
scaner();
if (fg==18) { // :=
scaner();
biaoda();
}
else {
printf("error!");
kk=1;
exit(0);
}
}
else if(fg==2){ // if
tiaojian();
scaner();
if(fg==3){
yuju();
}
else{
printf("error,lose 'then' ! \n");
kk=1;
exit(0);
}
}
else {
printf("error!");
kk=1;
exit(0);
}

return;
}
//条件
void tiaojian(){
biaoda();
if(fg==25||fg==0||fg==20||fg==21||fg==23||fg==24){
scaner();
}
else{
printf("error! \n");
kk=1;
exit(0);
}
biaoda();
return;
}
//表达式 
void biaoda(){
xiang();
while(fg==13 || fg==14) {
scaner();
xiang();
}
return;
}
//项 
void xiang(){
yinzi();
while(fg==15 || fg==16) {
scaner();
yinzi();
}
return;
}
//因子 
void yinzi(){
if(fg==10 || fg==11){
scaner (); // or identifier is an integer constant, a next read word symbols
}
the else IF (FG == 27) {
Scaner ();
biaoda ();
IF (FG == 28) {
Scaner ();
}
{the else
the printf ( " ')' error \ n-");
KK =. 1;
Exit (0);
}
} {the else
the printf ( "error expression \ n-");
KK =. 1;
Exit (0);
}
return;
}

int main (void) {
P = 0;
int I;
the printf ( "Please enter the source: \ n-");
do {
Scanf ( "% C", & CH);
Duru [P ++] = CH;
} the while (CH! = '#');
P = 0;
do {
Scaner ();
panduan ();
}! the while (FG = 0);
the printf ( "parsing end \ n!");

}

Screenshot below:

Guess you like

Origin www.cnblogs.com/dianshuizheng/p/11960152.html