实验2 递归下降语法分析程序设计
【開發語言及實現平臺或實驗環境】
C++/Clion
【實驗目的】
(1)理解語法分析在編譯程序中的作用,以及它與詞法分析程序的關系
(2)加深對遞歸下降語法分析原理的理解
(3)掌握遞歸下降語法分析的實現方法
【實驗內容】
編制一個遞歸下降分析程序,實現對詞法分析程序提供的單詞序列的語法檢查和結構分析。
【實驗要求】
(1)待分析的簡單語言的詞法同實驗1
(2)待分析的簡單語言的語法
用擴充的BNF表示如下:
1)<程序>::=begin<語句串>end
2) <語句串>::=<語句>{;<語句>}
3) <語句>::=<賦值語句>
4) <賦值語句>::=ID:=<表達式>
5) <表達式>::=<項>{+<項>|-<項>}
6) <項>::=<因子>{*<因子>|/<因子>}
7) <因子>::=ID|NUM|(<表達式>)
(3)語法分析程序的功能
輸入單詞串以”#”結束,如果是文法正確的句子,輸出成功信息;否則輸出錯誤信息。
例如:
輸入 begin a:=9; x:=2 * 3; b:=a + x end #
輸出 success
輸入 x:=a + b * c end #
輸出 error
【實驗步驟】
(1)根據圖2.1遞歸下降分析程序示意圖構建主程序框架
(2)編寫各語法單位分析函數
1)編寫語句串及語句分析函數
代碼提示:
2)編寫表達式分析過程
3)編寫項分析過程
4)編寫因子分析過程
(3)調試程序,驗證輸出結果
【實驗代碼】
#include<cstdio> #include<cstring> #include<iostream>using namespace std;char prog[80], token[8]; char ch; int syn, p, m, n, sum, kk; char *pString[6] = {"begin", "if", "then", "while", "do", "end"};int scanner(); //調用scanner函數 int lrparscr(); //調用lrparscr函數 int yucu(); //調用yucu函數 int statement(); //調用statement函數 int expression(); //調用expression函數 int term(); //調用term函數 int factor(); //調用factor函數int main() {p = 0;cout << "\nPlease input string:" << endl;do {cin.get(ch);prog[p++] = ch; //輸入源程序字符串,送到緩沖區prog[p++]中} while (ch != '#');p = 0;kk = 0;scanner();lrparscr();getchar();getchar();return 0; }int lrparscr() {if (syn == 1) {scanner(); //讀下一個單詞符號yucu();if (syn == 6) { //syn=6 對應單詞符號endscanner(); //讀下一個單詞符號if ((syn == 0) && (kk == 0))printf("success!\n");} else if (kk != 1) {cout << "出現缺end錯誤!" << endl;kk = 1;}} else {cout << "出現缺begin錯誤!" << endl;kk = 1;}return 0; }int yucu() { //語句串分析函數statement();while (syn == 26) {scanner(); //讀下一個單詞符號statement(); //調用statement函數}return 0; }int statement() {if (syn == 10) {scanner(); //讀下一個單詞符號if (syn == 18) {scanner(); //讀下一個單詞符號expression();} else {cout << "出現賦值號錯誤!" << endl;kk = 1;}} else {cout << "出現語句錯誤!" << endl;kk = 1;}return 0; }int expression() {term();while ((syn == 13) || (syn == 14)) {scanner(); //讀下一個單詞符號term();}return 0; }int term() {factor();while ((syn == 15) || (syn == 16)) {scanner(); //讀下一個單詞符號factor();}return 0; }int factor() {if ((syn == 10) || (syn == 11)) //是否是標識符或整型常數scanner(); //讀下一個單詞符號else if (syn == 27) { // 是否是 (scanner(); //讀下一個單詞符號expression();if (syn == 28) // 是否是 )syn = scanner(); //讀下一個單詞符號else {cout << "出現 ) 錯誤!" << endl;kk = 1;}} else {cout << "出現表達式錯誤!" << endl;kk = 1;}return 0; }int scanner() {for (n = 0; n < 8; n++) token[n] = '\0';ch = prog[p++]; //讀下一個單詞符號并賦給chwhile (ch == ' ') { //如果是空格,讀下一字符ch = prog[p];p++;}if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { //如果是字母字符m = 0;while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { //如果是字母字符token[m++] = ch; //當前字符送入tokench = prog[p++]; //讀下一個單詞符號并賦給ch}token[m++] = '\0'; //單詞結束p--; //回退一個字符syn = 10; //標識符for (n = 0; n < 6; n++) //與關鍵字表進行比較,確定syn的值if (strcmp(token, pString[n]) == 0) {syn = n + 1; //給出syn值break;}} else if ((ch >= '0' && ch <= '9')) { //如果是數字字符{sum = 0;while ((ch >= '0' && ch <= '9')) { //如果是數字字符sum = sum * 10 + ch - '0'; //ch送入sum,并更新數字ch = prog[p++]; //讀下一個單詞符號并賦給ch}}p--; //回退一個字符syn = 11; //數字字符if (sum > 32767)syn = -1; //出現錯誤} elseswitch (ch) { //其他字符時case '<':m = 0;token[m++] = ch;ch = prog[p++]; //讀下一個單詞符號并賦給chif (ch == '>') {syn = 21; //不等于token[m++] = ch;} else if (ch == '=') {syn = 22; //小于等于token[m++] = ch;} else {syn = 23; //大于p--; //回退一個字符}break;case '>':m = 0;token[m++] = ch;ch = prog[p++]; //讀下一個單詞符號并賦給chif (ch == '=') {syn = 24; //大于等于token[m++] = ch;} else {syn = 20; //小于p--; //回退一個字符}break;case ':':m = 0;token[m++] = ch;ch = prog[p++]; //讀下一個單詞符號并賦給chif (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;case '\n':syn = -2;break;default:syn = -1;break;}return syn; }【運行結果】
總結
以上是生活随笔為你收集整理的实验2 递归下降语法分析程序设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实验1 词法分析程序设计
- 下一篇: 面试题 16.18. Pattern M