編譯原理PL0語法分析實驗1
1,待分析的簡單語言的詞法
相同點:都是分析種別碼
不同點:詞法分析器分析的是字符串中的單詞的種別碼(單詞)
語法分析器分析的是字符串的文法是否正確(句子)
待分析的簡單語言的語法
BNF:
(1)<程序>::=begin<語句串>end
(2)<語句串>::=<語句>{;<語句>}
(3)<語句>::=<賦值語句>
(4)<賦值語句>::=ID:=<表達式>
(5)<表達式>::=<項>{+<項>|-<項>}
(6)<項>::=<因子{*<因子>|/<因子>}
語法分析程序的功能
輸入一個c語言的字符串,以#號結束,如果是文法正確的句子,那麼程序就會輸出成功信息;如果是文法錯誤的句子,那麼程序就會輸出錯誤的信息以及提示出錯點在哪裏
正確的文法:begin BNF文法 end#
【例1】
給定一個字符串,判斷語法是否正確:
輸入:begin a:=9;x:=2*3;b:=a+x end#
輸出:成功!
輸入:begin x:=a+b*c end
輸出:錯誤!“end”後出錯了
輸入:begin x:=a+b*c
輸出:錯誤!缺少“end”
輸入:x:=a+b*c end#
輸出:錯誤!缺少begin
程序驗證代碼(語法分析程序)
#include <studio.h> #include <string.h> void scaner(); void sentence(); void statement(); void expression(); void term(); void factor(); char *key[0]={"begin","if","then","while","do","end"},ch[100]; int p=0,kk=0,q,syn; int main() { printf("輸入:\n"); gets(ch); sentence(); return 0; } void scanner() { char token[100] = {}; q = 0; while(ch[p] == ' ') p++; if((ch[p] >= 'a' && ch[p] <= 'z')||(ch[p] >= 'A' && ch[p] <= 'Z') { token[q++] = ch[p]; p++; while((ch[p] >= '0' && ch[p] <= '9')||(ch[p] >= 'a' && ch[p] <= 'z') ||(ch[p] >= 'A' && ch[p] <= 'Z')) token[q++] = ch[p++]; syn = 10; token[q] = '\0'; for(int n = 0;n < 6;n++) { if(strcmp(token,key[n]) == 0) { syn = n + 1; break; } } } else if(ch[p] >= '0' && ch[p] <= '9') { token[q++] = ch[p]; p++; while(ch[p] >= '0' && ch[p] <= '9') token[q++] = ch[p++]; syn = 11; } else switch(ch[p]) { case '<': token[q++] = ch[p++]; if(ch[p] == '>') { syn = 21; token[q++] = ch[p++]; } else if(ch[p] == '=') { syn = 22; token[q++] = ch[p++]; } else syn = 23; break; case '>': token[q++] = ch[p++]; if(ch[p] == '>') { syn = 24; token[q++] = ch[p++]; } else syn = 20; break; case ':': token[q++] = ch[p++]; if(ch[p] == "="){ syn = 18; token[q++] = ch[p++]; } else syn = 17; token[q++] = ch[p++]; break; case '*': syn = 13; token[q++] = ch[p++]; break; case '/': syn = 14; token[q++] = ch[p++]; break; case '+': syn = 15; token[q++] = ch[p++]; break; case '-': syn = 16; token[q++] = ch[p++]; break; case '=': syn = 25; token[q++] = ch[p++]; break; case ';': syn = 26; token[q++] = ch[p++]; break; case '(': syn = 27; token[q++] = ch[p++]; break; case ')': syn = 28; token[q++] = ch[p++]; break; case '#': syn = 0; token[q++] = ch[p++]; break; case '\n': syn = -2; break; default: syn = -1; break; } } void sentence() { scaner(); if(syn == 1) { statement(); while(syn == 26) statement(); if(syn == 6) { scaner(); if(syn == 0) printf("成功!\n"); else printf("錯誤!“end”後出錯。\n"); } else { printf("錯誤!缺少“end”。\n"); kk = 1; } } else { printf("錯誤!缺少“begin”。\n"); kk = 1; } } void statement() { scaner(); if(syn == 10) { scaner(); if(syn == 18) { scaner(); expression(); } else { printf("錯誤!“:=”出錯。\n"); kk = 1; } } else { printf("錯誤!句子出錯。\n"); kk = 1; } return; } void expression() { term(); while((syn == 13)||(syn == 14)) { scaner(); term(); } return; } void term() { factor(); while((syn == 15)||(syn == 16)) { scaner(); factor(); } return; } void factor() { if((syn == 10)||(syn == 11)) scaner(); else if(syn == 27) { scaner(); expression(); if(syn == 28) scaner(); else { printf("錯誤!“(”出錯。\n"); kk = 1; } } else { printf("錯誤!\n"); kk = 1; } return; } //begin a:=9;x:=2*3;b:=a+x end# //begin x:a+b*c en
————————————————
版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
原文鏈接:https://blog.csdn.net/qq_44709970/article/details/121804295