1, Lexical analysis
1.1 experimental requirements
Prepare a word reading process, and identify each word with independent meaning from the input source program, namely basic reserved word, identifier, constant, operator and separator. The internal code of each word and the value of the word symbol are output.
Save the sample code in file 1 Txt, the program reads the file for lexical analysis. The example code is:
#include "math.h" main() { float a,b,y1,y2; int c,d,e; a=3.1415926; b=25.0; scanf("%d,%d",&c,&d); y1=cos(a/3); y2=sqrt(b); e=d+(-1); if(c>d&&c>0) e=c; printf("y1=%f,y2=%f,e=%d,c=%x\n",y1,y2,e,c); }
1.2 experimental code
#include<iostream> using namespace std; #define MAX 32 #define maxchar 200 /* *Identifier: 1 *Reserved word | keyword: 2 *Constant: 3 *Operator | operator: 4 *Separator: 5 */ char ch = ' '; char* keyWord[MAX] = { "auto","short","int","long","float","double","char","struct","union","enum","typedef","const", "unsigned","signed","extern","register","static","volatile","void","else","switch","case","for","do","while","goto", "continue","break","default","sizeof","return","if"}; char token[maxchar];//Defines the character to get //Determine whether it is a keyword bool isKey(char* token) { for (int i = 0; i < MAX; i++) { if (strcmp(token, keyWord[i]) == 0) return true; } return false; } //Determine whether it is a letter bool isLetter(char letter) { if ((letter >= 'a' && letter <= 'z') || (letter >= 'A' && letter <= 'Z')) return true; else return false; } //Judge whether it is a number bool isDigit(char digit) { if (digit >= '0' && digit <= '9') return true; else return false; } //Lexical analysis function void analyze(FILE* fpin) {//The fgetc function means to get the next character, and EOF means to read to the end of the file while ((ch = fgetc(fpin)) != EOF) { if (ch == ' ' || ch == '\t' || ch == '\n') {} //Remove spaces and carriage returns else if (isLetter(ch)) {//Judgment keywords and identifiers char token[maxchar] = { '\0' }; int i = 0; while (isLetter(ch) || isDigit(ch)) { token[i] = ch; i++; ch = fgetc(fpin); } //Fallback a pointer fseek(fpin, -1L, SEEK_CUR); if (isKey(token)) { //keyword cout << '(' << token << ',' << " 2" << ')' << "keyword" << endl; } else { //identifier cout << '(' << token << ',' << " 1" << ')' << "identifier " << endl; } } else if (isDigit(ch) )//Judge whether it is a number { int i = 0; char token[maxchar] = { '\0' }; while (isDigit(ch) || (ch == '.' && isDigit(fgetc(fpin))))//Integer or decimal (read one more digit) { if (ch == '.')fseek(fpin, -1L, SEEK_CUR); token[i] = ch; i++; ch = fgetc(fpin); } fseek(fpin, -1L, SEEK_CUR); cout << '(' << token << ',' << " 3" << ')' << "constant" << endl; } else switch (ch) { //operator case '+': { ch = fgetc(fpin); if (ch == '+') cout << '(' << "++" << ',' << " 4" << ')' << "operator" << endl; else { cout << '(' << "+" << ',' << " 4" << ')' << "operator" << endl; fseek(fpin, -1L, SEEK_CUR); } }break; case '-': { ch = fgetc(fpin); if (ch == '-') cout << '(' << "--" << ',' << " 4" << ')' << "operator" << endl; else { cout << '(' << "-" << ',' << " 4" << ')' << "operator" << endl; fseek(fpin, -1L, SEEK_CUR); } }break; case '&': { ch = fgetc(fpin); if (ch == '&') cout << '(' << "&&" << ',' << " 4" << ')' << "operator" << endl; else { cout << '(' << "&" << ',' << " 4" << ')' << "operator" << endl; fseek(fpin, -1L, SEEK_CUR); } }break; case '|': { ch = fgetc(fpin); if (ch == '|') cout << '(' << "||" << ',' << " 4" << ')' << "operator" << endl; else { cout << '(' << "|" << ',' << " 4" << ')' << "operator" << endl; fseek(fpin, -1L, SEEK_CUR); } }break; case '=': { ch = fgetc(fpin); if (ch == '=')cout << '(' << "==" << ',' << " 4" << ')' << "operator" << endl; else { cout << '(' << "=" << ',' << " 4" << ')' << "operator" << endl; fseek(fpin, -1L, SEEK_CUR); } }break; case ':': { ch = fgetc(fpin); if (ch == '=')cout << '(' << ":=" << ',' << " 4" << ')' << "operator" << endl; else { cout << '(' << ":" << ',' << " 4" << ')' << "operator" << endl; fseek(fpin, -1L, SEEK_CUR); } }break; case '>': { ch = fgetc(fpin); if (ch == '=')cout << '(' << ">=" << ',' << " 4" << ')' << "operator" << endl; else { cout << '(' << ">" << ',' << " 4" << ')' << "operator" << endl; fseek(fpin, -1L, SEEK_CUR); } }break; case '<': { ch = fgetc(fpin); if (ch == '=')cout << '(' << "<=" << ',' << " 4" << ')' << "operator" << endl; else { cout << '(' << "<" << ',' << " 4" << ')' << "operator" << endl; fseek(fpin, -1L, SEEK_CUR); } }break; case '*':cout << '(' << ch << ',' << " 4" << ')' << "operator" << endl; break; case '%':cout << '(' << ch << ',' << " 4" << ')' << "operator" << endl; break; case '/':cout << '(' << ch << ',' << " 4" << ')' << "operator" << endl; break; //Delimiter case '"':cout << '(' << ch << ',' << " 5" << ')' << "Delimiter" << endl; break; case '(':cout << '(' << ch << ',' << " 5" << ')' << "Delimiter" << endl; break; case ')':cout << '(' << ch << ',' << " 5" << ')' << "Delimiter" << endl; break; case '[':cout << '(' << ch << ',' << " 5" << ')' << "Delimiter" << endl; break; case ']':cout << '(' << ch << ',' << " 5" << ')' << "Delimiter" << endl; break; case ';':cout << '(' << ch << ',' << " 5" << ')' << "Delimiter" << endl; break; case '{':cout << '(' << ch << ',' << " 5" << ')' << "Delimiter" << endl; break; case '}':cout << '(' << ch << ',' << " 5" << ')' << "Delimiter" << endl; break; case ',':cout << '(' << ch << ',' << " 5" << ')' << "Delimiter" << endl; break; case '.':cout << '(' << ch << ',' << " 5" << ')' << "Delimiter" << endl; break; case '#': cout < <' ('< ch < <', '< "5" <') '< "delimiter" < < endl; break; case '\\':cout << '(' << ch << ',' << " 5" << ')' << "Delimiter" << endl; break; } } }
1.3 experimental results
2, LL(1) analytical method
2.1 experimental requirements
The purpose of this experiment is to deepen the understanding of predictive analysis LL (1) analysis method.
Simple requirements: at least use LL (1) analysis method to analyze any input symbol string for the following known grammars
1)E->TG
2)G->+TG
3)G->ε
4)T->FS
5)S->*FS
6)S->ε
7)F->(E)
8)F->I
High requirements:
1. Manual input grammar
2. Displays the Follow set of non terminators for the grammar
3. Displays an optional collection of rules
3. Structural prediction analysis table
4. Analyze any input symbol string
2.2 experimental code
#include<stdio.h> #include<string.h> #include<stdlib.h> char A[20];/*Analysis stack*/ char B[20];/*Residual string*/ char v1[20] = { 'i','+','*','(',')','#' };/* Terminator*/ char v2[20] = { 'E','G','T','S','F' };/*Non Terminator */ int j = 0, b = 0, top = 0, l, m, n;/*l Is the input string length */ char ch, x;/*x Is the top character of the current stack*/ int k = 1, flag = 0, finish = 0; typedef struct type/*Production type definition */ { char origin;/*Uppercase character */ char array[5];/*Production right character */ int length;/*Number of characters */ }type; void print()/*Output analysis stack */ { int a; /*Pointer*/ for (a = 0; a <= top + 1; a++) printf("%c", A[a]); printf("\t\t"); } void print1()/*Output remaining string*/ { int j; for (j = 0; j < b; j++) printf(" "); for (j = b; j <= l; j++) printf("%c", B[j]); printf("\t\t\t"); } int main() { type e, t, g, g1, s, s1, f, f1, cha;/*Structure variable */ type C[10][10];/*Forecast analysis table */ /*Assign grammar production to structure*/ e.origin = 'E'; strcpy_s(e.array, "TG"); e.length = 2;/*Change length assignment*/ t.origin = 'T'; strcpy_s(t.array, "FS"); t.length = 2;/*Change length assignment*/ g.origin = 'G'; strcpy_s(g.array, "+TG"); g.length = 3;/*Change length assignment*/ g1.origin = 'G'; g1.array[0] = '^'; g1.array[1] = '\0';/*Change string end flag*/ g1.length = 1;/*Change length assignment*/ s.origin = 'S'; strcpy_s(s.array, "*FS"); s.length = 3;/*Change length assignment*/ s1.origin = 'S'; s1.array[0] = '^'; s1.array[1] = '\0';/*Change string end flag*/ s1.length = 1;/*Change length assignment*/ f.origin = 'F'; strcpy_s(f.array, "(E)"); f.length = 3;/*Change length assignment*/ f1.origin = 'F'; f1.array[0] = 'i'; f1.array[1] = '\0';/*Change string end flag*/ f1.length = 1;/*Change length assignment*/ for (m = 0; m <= 4; m++)/*Initialize analysis table*/ for (n = 0; n <= 5; n++) C[m][n].origin = 'N';/*Empty all*/ /*Fill analysis table*/ C[0][0] = e; C[0][3] = e; C[1][1] = g; C[1][4] = g1; C[1][5] = g1; C[2][0] = t; C[2][3] = t; C[3][1] = s1; C[3][2] = s; C[3][4] = C[3][5] = s1; C[4][0] = f1; C[4][3] = f; printf("The characters that can be entered are\'i\',\'+\',\'*\',\'(\',\')\',\'#\'Note: take the first\'#\'end as string: \ n ""); do/*Read in analysis string*/ { scanf_s("%c", &ch); if ((ch != 'i') && (ch != '+') && (ch != '*') && (ch != '(') && (ch != ')') && (ch != '#')) { printf("Error!Illegal character in input string!\n"); exit(1); } B[j] = ch; j++; } while (ch != '#'); printf("The process of string analysis is as follows:\n"); l = j;/*Analysis string length*/ ch = B[0];/*Current analysis character*/ A[top] = '#'; A[++top] = 'E';/*'#','E'Enter the stack*/ printf("step\t\t Analysis stack\t\t Remaining characters\t\t Production used \n"); /*The derivation process is as follows*/ do { x = A[top--];/*x Is the top character of the current stack*/ printf("%d", k++);/*Step No*/ printf("\t\t"); for (j = 0; j <= 5; j++)/*Determine whether it is a terminator*/ if (x == v1[j]) { flag = 1; break; } if (flag == 1)/*If Terminator*/ { if (x == '#') { if (ch == '#') { finish = 1;/*End tag*/ print();/*Align on last successful change*/ print1(); printf("acc!\n");/*accept */ printf("The input string conforms to the grammar!\n"); getchar(); getchar(); exit(1); } else { print(); print1(); printf("Error!\n"); printf("The current analysis stack is#, but there are still characters in the remaining string that do not match. \n"); printf("The input string does not conform to the grammar!\n"); getchar(); getchar(); exit(0); } } if (x == ch) { print(); print1(); printf("%c matching\n", ch); ch = B[++b];/*Next input character*/ flag = 0;/*Recovery tag*/ } else { if (ch == '#') { print(); print1(); printf("Error!\n"); printf("The remaining string is#, but there are still characters unmatched in the analysis stack. \n"); printf("The input string does not conform to the grammar!\n"); getchar(); getchar(); exit(0); } else { print(); print1(); printf("Error!%c Matching error\n", ch);/*Output error Terminator*/ printf("Does not match the current input character!\n"); printf("The input string does not conform to the grammar!\n"); getchar(); getchar(); exit(1); } } } else/*Non terminator processing*/ { for (j = 0; j <= 4; j++) if (x == v2[j]) { m = j;/*Line number*/ break; } for (j = 0; j <= 5; j++) if (ch == v1[j]) { n = j;/*Column number*/ break; } cha = C[m][n];/*Production of recording application*/ if (cha.origin != 'N') { print(); print1(); printf("%c->", cha.origin); for (j = 0; j < cha.length; j++) printf("%c", cha.array[j]); printf("\n"); for (j = (cha.length - 1); j >= 0; j--) { A[++top] = cha.array[j]; if (A[top] == '^')/*If it is empty, it will not be stacked*/ top--; } } else { print(); print1(); printf("Error!\n"); printf("The current stack top element is a non terminator, but the corresponding production of the current input character cannot be found!\n"); printf("The input string does not conform to the grammar!\n"); getchar(); getchar(); exit(0); } } } while (true); return 0; }
2.3 experimental results
3, Generation and calculation of inverse wave
3.1 experimental requirements
Convert the arithmetic expression represented by infix into the arithmetic expression represented by inverse Polish, and calculate the value of the arithmetic expression represented by inverse Polish.
3.2 experimental code
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> using namespace std; const int StackSize = 30;//Stack size char result[100];//It is used to store the conversion results for easy output, and spaces can be added char num;//Count the result array //Define stack structure typedef struct Stack { char data[StackSize]; int top; }StackType; //Out of stack char Pop(StackType *p) { if(p->top == -1) //Whether the stack is empty is determined when the stack is out of the stack { printf("Stack empty\n"); exit(0);//exit(0) means to exit the program normally, and exit(1) means to exit the program due to abnormal operation; } return p->data[p->top--];//After the stack top element returns, subtract the stack top pointer by one } //Enter the stack void Push(StackType *p, char dat) { if(p->top == StackSize -1)//Enter the stack to judge whether the stack is full { printf("Stack full\n"); exit(0); } p->data[++p->top] = dat;//Add one to the top of the stack pointer to put dat on the stack } //Get the data at the top of the stack char GetTop(StackType *p) { if(p->top != -1) return p->data[p->top]; return 0; } //Determine whether it is an operator or an operand bool isNumber(char op) { switch(op) { case ' ': case '(': case ')': case '+': case '-': case '*': case '/': case '#': return 0;// Returns 0 if op is an operator default : return 1;//Returns 1 if op is an operand } } //Gets the priority of the operator, 1 is the highest, and the priority is counted int priority(char ch) { int value= 10; //Set the initial value of value to minimize the priority of spaces switch(ch) { case '*': value = 2; break; case '/': value = 2; break; case '+': value = 3; break; case '-': value = 3; break; case '(': case ')': value = 4; break;//When the left bracket is encountered, all symbols will be stacked until the right bracket is encountered case '#': value = 5; break;//'#' has the lowest priority among operators default: break; } return value; } //Solving inverse Polish principal function void NiBoLan(char arr[]) { StackType* pStack = new StackType; pStack->top = -1;//Initialization stack is empty char ch;//ch represents the operator for(int i=0;arr[i] != '\0';i++)//'\ 0', which is a null character. The flag to judge whether a string ends is to see whether '\ 0' is encountered. If '\ 0', it indicates the end of the string { if(isNumber(arr[i])) { result[num++] = arr[i];//If arr[i] is an operand, it is placed in the result array and output later } else//If arr[i] is not an object, it is an operator { //First, judge whether the stack is empty. If the stack is empty, enter the stack if(pStack->top==-1 || arr[i] == '(') { Push(pStack, arr[i]); continue; } if(arr[i] == '#')//End symbol (the first entry is' # 'break, and continue to cycle to judge the next symbol) break; if(arr[i] == ')')//When the closing parenthesis') 'is read, it is out of the stack { result[num++] = ' '; while((ch = Pop(pStack)) != '(' )//Start out of the stack until the left bracket '(' is encountered at the top of the stack { result[num++] = ch; } continue; } result[num++] = ' '; ch = priority(GetTop(pStack)) - priority(arr[i]);//Compare priorities and obtain the results after priority comparison. However, when ch > 0, the operator priority is greater than the top of the stack, = 0 is equal, and < 0 is less than //The priority is greater than the top of the stack (the smaller the value, the greater the priority; for example, the top of the stack is + and its value is 3, * its value is 2, but * priority is higher than + but ch = 3-2 = 1 > 0 if(ch > 0) { //Stack with high priority Push(pStack, arr[i]); } //Priority is less than or equal to the top of the stack else if(ch <= 0) { //It should be out of the stack, and then judge the priority. If it is not empty, continue to judge the priority, and then put arr[i] into the stack while( priority(arr[i]) >= priority(GetTop(pStack)))//When the priority of this operator is less than or equal to the top of the stack, it is always output { result[num++] = Pop(pStack); result[num++] = ' '; } Push(pStack, arr[i]); } } } while(GetTop(pStack) != '#'/ / perfection in the previous operation, all the elements in the stack may not be out of the stack { result[num++] = ' '; result[num++] = Pop(pStack); } for(int i=0;i<num;i++) //Traverse the result array and output printf("%c",result[i]); } //Calculates the value of the suffix expression int Calculate(char arr[]) { int i, cal[100],top=-1; memset(cal,0,sizeof(cal));//The memset function means to empty the stack for(i=0;i<num;i++) { if(isNumber(arr[i]))//Judge whether it is an operator, return 1, no, what comes in can only be numbers { //Simulation stack top++; while(arr[i] != ' ')//Get an integer and merge it into the stack { cal[top] = cal[top]*10 + arr[i++]-48; } } else { switch(arr[i]) { //Simulated out of stack case '+': cal[top-1] = cal[top-1] + cal[top]; cal[top--] = 0; break; case '-': cal[top-1] = cal[top-1] - cal[top]; cal[top--] = 0; break; case '*': cal[top-1] = cal[top-1] * cal[top]; cal[top--] = 0; break; case '/': cal[top-1] = cal[top-1] / cal[top]; cal[top--] = 0; break; default: break; } } } return cal[0]; } int main(void) { char express[] ="#21+((42-2)*15+6)-18#"; / / the answer is 609 //char express[] ="30*(40+20)/2-50#";// The answer is 850 printf("Infix expression:"); printf("%s\n", express); printf("Suffix expression:"); NiBoLan(express); printf("\n"); printf("The calculation result is:%d\n", Calculate(result)); return 0; }
3.3 experimental results
4, Algorithm priority analysis
4.1 experimental requirements
Understand the syntax analysis method of expression with operator priority method, and master the manual construction method of top-down predictive syntax analysis program.
The requirements are as follows: the basic functions of an interactive object-oriented operator priority analyzer are:
(1) Input grammar rules
(2) Convert grammar
(3) Generate FirstVT and LastVT for each non terminator
(4) Generate operator priority analysis table
(5) Then enter the grammar symbol string
(6) Generate move in protocol steps
Test case: e - > e + T; E->T; T->T*F; T->F; F->(E); F->i
4.2 experimental code
#include "stdio.h" #include "stdlib.h" #include "iostream" using namespace std; char data[20][20]; //Operator precedence relation char s[100]; //Analog symbol stack s char lable[20]; //Grammar ultimate symbol set char input[100]; //Grammar input symbol string char ch[20][10]; //Analysis for input string int k; char a; int j; char q; int r; //Number of grammar rules int r1; int m,n,N; //Number of grammar rules after conversion char st[10][30]; //Used to store grammar rules char first[10][10]; //Grammar non terminator FIRSTVT set char last[10][10]; //Grammar non terminator LASTVT set int fflag[10]={0}; //Indicates whether the FIRSTVT set of the ith non terminator has been evaluated int lflag[10]={0}; //Flag whether the LASTVT set of the ith non terminator has been evaluated int deal(); //Analysis of input string int zhongjie(char c); //Determine whether the character c is the ultimate character int xiabiao(char c); //Find the subscript of character c in the operator priority relationship table void out( int j,int k,char *s); //Print s stack void firstvt(char c); //Find the FIRSTVT set of non terminator c void lastvt(char c); //Find LASTVT set of non terminator c void table(); //Create grammar precedence table void main() { int i,j,k=0; printf("Please enter the number of grammar rules:"); scanf("%d",&r); printf("Please enter grammar rules:\n"); for(i=0;i<r;i++) { scanf("%s",st[ i]); //Store grammar rules and initialize FIRSTVT set and LASTVT set*/ first[i][0]=0; /* first[i][0]And last[i][0] respectively indicate that st[i][0] is not ultimate Number of elements in FIRSTVT set and LASTVT set of */ last[i][0]=0; } for(i=0;i<r;i++) //Judge whether grammar is legal { for(j=0;st[i][j]!='\0';j++) { if(st[i][0]<'A'||st[i][0]>'Z') { printf("Not operator grammar!\n"); exit(-1); } if(st[i][j]>='A'&&st[i][j]<='Z') { if(st[i][j+1]>='A'&&st[i][j+1]<='Z') { printf("Not operator grammar!\n"); exit(-1); } } } } for(i=0;i<r;i++) { for(j=0;st[i][j]!='\0';j++) { if((st[i][j]<'A'||st[i][j]>'Z')&&st[i][j]!='-'&&st[i][j]!='>'&&st[i][j]!='|') lable[k++]=st[i][j]; } } lable[k]='#'; lable[k+1]='\0'; table(); printf("Of each non Terminator FIRSTVT Set to: \n"); //Outputs the FIRSTVT set for each non terminator for(i=0;i<r;i++) { printf("%c: ",st[i][0]); for(j=0;j<first[i][0];j++) { printf("%c ",first[i][j+1]); } printf("\n"); } printf("Of each non Terminator LASTVT Set to: \n"); //Outputs the LASTVT set for each non terminator for(i=0;i<r;i++) { printf("%c: ",st[i][0]); for(j=0;j<last[i][0];j++) { printf("%c ",last[i][j+1]); } printf("\n"); } printf("The operator priority analysis table is as follows:\n"); for(i=0;lable[i]!='\0';i++) printf("\t%c",lable[i]); printf("\n"); for(i=0;i<k+1;i++) { printf("%c\t",lable[i]); for(j=0;j<k+1;j++) { printf("%c\t",data[i][j]); } printf("\n"); } printf("Please enter a grammar string to#End: "; scanf("%s",input); deal(); } void table() { char text[20][10]; int i,j,k,t,l,x=0,y=0; int m,n; x=0; for(i=0;i<r;i++) { firstvt(st[i][0]); lastvt(st[i][0]); } for(i=0;i<r;i++) { text[x][y]=st[i][0]; y++; for(j=1;st[i][j]!='\0';j++) { if(st[i][j]=='|') { text[x][y]='\0'; x++; y=0; text[x][y]=st[i][0]; y++; text[x][y++]='-'; text[x][y++]='>'; } else { text[x][y]=st[i][j]; y++; } } text[x][y]='\0'; x++; y=0; } r1=x; printf("The converted grammar is:\n"); for(i=0;i<x;i++) //Output converted grammar rule string { printf("%s\n",text[i]); } for(i=0;i<x;i++) /* Find the derivation result of each Terminator (remove "-") Post conversion grammar for final specification) */ { ch[i][0]=text[i][0]; for(j=3,l=1;text[i][j]!='\0';j++,l++) ch[i][l]=text[i][j]; ch[i][l]='\0'; } for(i=0;i<x;i++) { for(j=1;text[i][j+1]!='\0';j++) { if(zhongjie(text[i][j])&&zhongjie(text[i][j+1])) { m=xiabiao(text[i][j]); n=xiabiao(text[i][j+1]); data[m][n]='='; } if(text[i][j+2]!='\0'&&zhongjie(text[i][j])&&zhongjie(text[i][j+2])&&!zhongjie(text[i][j+1])) { m=xiabiao(text[i][j]); n=xiabiao(text[i][j+2]); data[m][n]='='; } if(zhongjie(text[i][j])&&!zhongjie(text[i][j+1])) { for(k=0;k<r;k++) { if(st[k][0]==text[i][j+1]) break; } m=xiabiao(text[i][j]); for(t=0;t<first[k][0];t++) { n=xiabiao(first[k][t+1]); data[m][n]='<'; } } if(!zhongjie(text[i][j])&&zhongjie(text[i][j+1])) { for(k=0;k<r;k++) { if(st[k][0]==text[i][j]) break; } n=xiabiao(text[i][j+1]); for(t=0;t<last[k][0];t++) { m=xiabiao(last[k][t+1]); data[m][n]='>'; } } } } m=xiabiao('#'); for(t=0;t<first[0][0];t++) { n=xiabiao(first[0][t+1]); data[m][n]='<'; } n=xiabiao('#'); for(t=0;t<last[0][0];t++) { m=xiabiao(last[0][t+1]); data[m][n]='>'; } data[n][n]='='; } void firstvt(char c) //Find FIRSTVT set { int i,j,k,m,n; for(i=0;i<r;i++) { if(st[i][0]==c) break; } if(fflag[i]==0) { n=first[i][0]+1; m=0; do { if(m==2||st[i][m]=='|') { if(zhongjie(st[i][m+1])) { first[i][n]=st[i][m+1]; n++; } else { if(zhongjie(st[i][m+2])) { first[i][n]=st[i][m+2]; n++; } if(st[i][m+1]!=c) { firstvt(st[i][m+1]); for(j=0;j<r;j++) { if(st[j][0]==st[i][m+1]) break; } for(k=0;k<first[j][0];k++) { int t; for(t=0;t<n;t++) { if(first[i][t]==first[j][k+1]) break; } if(t==n) { first[i][n]=first[j][k+1]; n++; } } } } } m++; }while(st[i][m]!='\0'); first[i][n]='\0'; first[i][0]=--n; fflag[i]=1; } } void lastvt(char c) //Find LASTVT set { int i,j,k,m,n; for(i=0;i<r;i++) { if(st[i][0]==c) break; } if(lflag[i]==0) { n=last[i][0]+1; m=0; do { if(st[i][m+1]=='\0'||st[i][m+1]=='|') { if(zhongjie(st[i][m])) { last[i][n]=st[i][m]; n++; } else { if(zhongjie(st[i][m-1])) { last[i][n]=st[i][m-1]; n++; } if(st[i][m]!=c) { lastvt(st[i][m]); for(j=0;j<r;j++) { if(st[j][0]==st[i][m]) break; } for(k=0;k<last[j][0];k++) { int t; for(t=0;t<n;t++) { if(last[i][t]==last[j][k+1]) break; } if(t==n) { last[i][n]=last[j][k+1]; n++; } } } } } m++; }while(st[i][m]!='\0'); last[i][n]='\0'; last[i][0]=--n; lflag[i]=1; } } int deal() { int i,j; int x,y; int z; //Enter the length of the string k=1; s[k]='#'; // Stack initial value for(i=0;input[i]!='\0';i++); //Calculates the length of the input string z=i--; i=0; while((a=input[i])!='\0') { if(zhongjie(s[k])) j=k; else j=k-1; x=xiabiao(s[j]); y=xiabiao(a); if(data[x][y]=='>') { out(1,k,s); printf("%c",a); out(i+1,z,input); printf("Statute\n"); do { q=s[j]; if(zhongjie(s[j-1])) j=j-1; else j=j-2; x=xiabiao(s[j]); y=xiabiao(q); }while(data[x][y]!='<'); int m,n,N; for(m=j+1;m<=k;m++) { for(N=0;N<r1;N++) for(n=1;ch[N][n]!='\0';n++) { if(!zhongjie(s[m])&&!zhongjie(ch[N][n])) { if(zhongjie(s[m+1])&&zhongjie(ch[N][n+1]) &&s[m+1]==ch[N][n+1]) { s[j+1]=ch[N][0]; break; } } else if(zhongjie(s[m])) if(s[m]==ch[N][n]) { s[j+1]=ch[N][0]; break; } } } k=j+1; if(k==2&&a=='#') { out(1,k,s); printf("%c",a); out(i+1,z,input); printf("end\n"); printf("The input string conforms to the definition of grammar!\n"); return 1; //The input string conforms to the definition of grammar } } else if(data[x][y]=='<'||data[x][y]=='=') { //Move in out(1,k,s); printf("%c",a); out(i+1,z,input); printf("Move in\n"); k++; s[k]=a; i++; } else { printf("\nflase"); return 0; } } printf("\nflase"); return 0; } void out(int j,int k,char *s) { int n=0; int i; for(i=j;i<=k;i++) { printf("%c",s[i]); n++; } for(;n<15;n++) { printf(" "); } } int xiabiao(char c) //Find the subscript of character c in the operator priority relationship table { int i; for(i=0;lable[i]!='\0';i++) { if(c==lable[i]) return i; } return -1; } int zhongjie(char c) //Determine whether the character c is the ultimate character { int i; for(i=0;lable[i]!='\0';i++) { if(c==lable[i]) return 1; } return 0; }
4.3 experimental results
5, LR(1) analysis method
5.1 test requirements
Parse any input string according to the LR (1) analysis table established by grammar rules in advance. It is required to output the analysis process table.
5.2 experimental code
#include<stdio.h> #include<string.h> const char* action[10][3] = { "S3#","S4#", NULL, /*ACTION table*/ NULL,NULL,"acc", "S6#","S7#",NULL, "S3#","S4#",NULL, "r3#","r3#",NULL, NULL,NULL,"r1#", "S6#","S7#",NULL, NULL,NULL,"r3#", "r2#","r2#",NULL, NULL,NULL,"r2#" }; int goto1[10][2] = { 1,2, /*QOTO surface */ 0,0, 0,5, 0,8, 0,0, 0,0, 0,9, 0,0, 0,0, 0,0 }; char vt[3] = { 'a','b','#' }; /* Store non Terminator*/ char vn[2] = { 'S','B' }; /* Store Terminator */ const char* LR[4] = { "E->S#","S->BB#","B->aB#","B->b#"}; / * store production*/ int a[10]; char b[10], c[10], c1; int top1, top2, top3, top, m, n; void main() { int g, h, i, j, k, l, p, y, z, count; char x, copy[10], copy1[10]; top1 = 0; top2 = 0; top3 = 0; top = 0; a[0] = 0; y = a[0]; b[0] = '#'; count = 0; z = 0; printf(" Please enter an expression \n"); do { scanf_s("%c", &c1); c[top3] = c1; top3 = top3 + 1; } while (c1 != '#'); printf("step\t State stack\t\t Symbol stack\t\t Input string\t\tACTION\tGOTO\n"); do { y = z; m = 0; n = 0; /*y,z Point to the top of the status stack */ g = top; j = 0; k = 0; x = c[top]; count++; printf("%d\t", count); while (m <= top1) { /* Output status stack */ printf("%d", a[m]); m = m + 1; } printf("\t\t"); while (n <= top2) { /* Output symbol stack */ printf("%c", b[n]); n = n + 1; } printf("\t\t"); while (g <= top3) { /* Output input string */ printf("%c", c[g]); g = g + 1; } printf("\t\t"); while (x != vt[j] && j <= 2) j++; if (j == 2 && x != vt[j]) { printf("error\n"); return; } if (action[y][j] == NULL) { printf("error\n"); return; } else strcpy_s(copy, action[y][j]); if (copy[0] == 'S') { /* Process move in */ z = copy[1] - '0'; top1 = top1 + 1; top2 = top2 + 1; a[top1] = z; b[top2] = x; top = top + 1; i = 0; while (copy[i] != '#') { printf("%c", copy[i]); i++; } printf("\n"); } if (copy[0] == 'r') { /* Processing reduction */ i = 0; while (copy[i] != '#') { printf("%c", copy[i]); i++; } h = copy[1] - '0'; strcpy_s(copy1, LR[h]); while (copy1[0] != vn[k]) k++; l = strlen(LR[h]) - 4; top1 = top1 - l + 1; top2 = top2 - l + 1; y = a[top1 - 1]; p = goto1[y][k]; a[top1] = p; b[top2] = copy1[0]; z = p; printf("\t"); printf("%d\n", p); } } while (action[y][j] != "acc"); printf("acc\n"); }
5.3 experimental results