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
Fifth, the experimental source:
#include<stdio.h> #include<string.h> #include<stdlib.h> char PROG [] = " A + B * # 20 is " , token [ 20 is ]; // Block, word symbols char CH; int SYN, P, m, n-, SUM; // word SYN symbol type, integer SUM char rwtab * [ . 6 ] = { " the begin " , " IF " , " the then " , " the while " , " do " , " End " }; void E(); void T(); void E1(); void T1(); void F(); void error(); void scanner() { for (n=0;n<20;n++) token[n]=NULL; m=0; sum=0; ch=prog[p++]; while (ch==' ') {ch=prog[p++];} if (ch>='a' && ch<='z') {while (ch>='a' && ch<='z'||ch>='0' && ch<='9') { token[m++]=ch; CH = prog [i ++ ]; } syn=10;p--; for(n=0;n<6;n++) if(strcmp(token,rwtab[n])==0) {syn=n+1;break;} } else if(ch>='0' && ch<='9') {while (ch>='0' && ch<='9') { sum=sum*10+(ch-'0'); CH = prog [i ++ ]; } syn = 11 ; p-- ; } else switch(ch) { case '<': token[m++]=ch; ch=prog[p++]; if (ch=='>') {syn=21;token[m++]=ch;} else if (ch=='='){syn=22;token[m++]=ch;} else {syn=20;p--;} break; case '>': m=0; token[m++]=ch; ch=prog[p++]; if (ch=='=') {syn=24;token[m++]=ch;} else {syn=23;p--;} break; case ':': m=0; token[m++]=ch; ch=prog[p++]; if (ch=='=') {syn=18;token[m++]=ch;} else {syn=17;p--;} break; case '+': syn=13;token[0]=ch;break; case '-': syn=14;token[0]=ch;break; case '*': syn=15;token[0]=ch;break; case '/': syn=16;token[0]=ch;break; case '=': syn=25;token[0]=ch;break; case ';': syn=26;token[0]=ch;break; case '(': syn=27;token[0]=ch;break; case ')': syn=28;token[0]=ch;break; case '#': syn=0; token[0]=ch;break; default : syn=-1;token[0]=ch; } } void E() { T(); E1 (); } void E1() { if (syn==13) { scanner(); T(); E1 (); } else if (syn == 0 || view == 28 ) { } else error(); } void T() { F(); T1 (); } void T1() { if(syn==15){ scanner(); F(); T1 (); } else clauses the if (syn == 0 || syn == 28 || syn == 13 ) { } else error(); } void F() { if (syn==27){ scanner(); E(); if (syn==28) scanner(); else error(); } else if (syn == 11 || view == 10 ) scanner(); else error(); } void error() { the printf ( " \ n-(% S, Error)! " , token); } main() { scanner(); E(); }