生活随笔
收集整理的這篇文章主要介紹了
pl/0词法分析器
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
下面是這個分析器的功能:
1、 ? ?待分析的簡單語言的詞法
(1)??? 關鍵字:
begin? if?? then?? while?? do?? end
所有關鍵字都是小寫。
(2)??? 運算符和界符:
: = ??+?? –?? *?? /?? <?? <=?? <>?? >?? >=?? =?? ;?? (?? )?? #
(3)??? 其他單詞是標識符(ID)和整型常數(NUM),通過以下正規(guī)式定義:
ID=letter(letter| digit)*
NUM=digit digit *
(4)??? 空格由空白、制表符和換行符組成。空格一般用來分隔ID、NUM,運算符、界符和關鍵字,詞法分析階段通常被忽略。
2、 ?各種單詞符號對應的種別碼
詞法分析程序的功能
輸入:所給文法的源程序字符串。
輸出:二元組(syn,token或sum)構成的序列。
其中:syn為單詞種別碼;
token為存放的單詞自身字符串;
sum為整型常數。
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>using namespace std;#define CODE "E:\\code\\code.txt"
#define RESULT "E:\\code\\result.txt"//token數組用來接收關鍵字,變量,運算符和界符
//這里限制變量名的長度最多為9
//prog數組存儲的是源代碼字符串長度
char *prog, token[10];
char ch;
//syn是各個單詞符號對應的數字
int syn, p, m = 0, n, line, sum = 0;
//rwtab數組存儲的是關鍵字
char *rwtab1[10] = { "begin","if","then","while","do","end" };
char *rwtab2[4] = { "const","var","procedure","call" };void scaner()
{//規(guī)定,標識符只能由字母或數字構成/*共分為三大塊,分別是標示符、數字、符號,對應下面的 if else if 和 else*///將全部置空for (n = 0; n<10; n++)//token為已捕獲的字符數token[n] = NULL;ch = prog[p++];//這樣處理,可以去除空格while (ch == ' '){ch = prog[p];p++;}//在這個if判斷中,范圍是a-z或者A-Z,因為規(guī)定變量只能以字母開頭if ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z')) //可能是標示符或者變量名{m = 0;//這里,是變量的第一個字符以后,可以是字母,數字while ((ch >= '0'&&ch <= '9') || (ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z')){token[m++] = ch;ch = prog[p++];}//變量的字符串結束標志token[m++] = '\0';p--;syn = 10;//將識別出來的字符和已定義的標示符作比較, 判斷是否是關鍵字,所有關鍵字都是小寫for (n = 0; n<6; n++)if (strcmp(token, rwtab1[n]) == 0){syn = n + 1;break;}for (n = 0; n < 4;n++){if (strcmp(token, rwtab2[n]) == 0){syn = n + 31;break;}}}else if ((ch >= '0'&&ch <= '9')) //數字 ,如果是數字,就用sum來保存這個數字{sum = 0;while ((ch >= '0'&&ch <= '9')){//這里*10是只考慮十進制數sum = sum * 10 + ch - '0';ch = prog[p++];}p--;syn = 11;//可接收的數字的最大值為32767,如果更大,會報錯if (sum>32767)syn = -1;}else switch (ch) //如果是其他的字符{case '<':m = 0;token[m++] = ch;ch = prog[p++];if (ch == '>'){//說明是不等號syn = 21;token[m++] = ch;}else if (ch == '='){//說明是<=syn = 22;token[m++] = ch;}else{//否則,就只是一個<符號syn = 23;//此時p回退一個p--;}break;case '>':m = 0;token[m++] = ch;ch = prog[p++];if (ch == '='){syn = 24;token[m++] = ch;}else{syn = 20;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 = 29;token[0] = ch;break;case '!':syn = 30;token[0] = ch;break;case '.'://如果接收到的是.,說明到了源代碼的結尾,置syn=0,函數結束syn = 0;token[0] = ch;break;case '\n'://如果接收到的是換行符,則syn=-2,行+1syn = -2;break;default://如果接收到的是其他未定義的字符,置syn=-1,會報錯。syn = -1;break;}
}/*
讀取源代碼文件(.txt)
*/
void read()
{FILE *fp;fp = fopen(CODE, "r");fseek(fp, 0, SEEK_END);int file_size;file_size = ftell(fp);fseek(fp, 0, SEEK_SET);prog = (char *)malloc(file_size * sizeof(char));fread(prog, file_size, sizeof(char), fp);//關閉文件流fclose(fp);
}int main()
{int p = 0;int line = 1;ofstream outfile(RESULT);cout<< "加載代碼文件中......" << endl;Sleep(3000);//讀取源代碼文件read();p = 0;outfile << "詞法分析的結果為:" << endl;do{scaner();switch (syn){case 11://cout << "(" << syn << "," << sum << ")" << endl;outfile << "(" << syn << "," << sum << ")" << endl;break;case -1://cout << "Error in line " << line << "!" << endl;outfile << "Error in line" << line << "!" << endl;break;case -2:line = line++;break;default://cout << "(" << syn << "," << token << ")" << endl;outfile << "(" << syn << "," << token << ")" << endl;break;}} while (syn != 0);outfile.close();cout << "詞法分析完畢,請在result.txt中查看" << endl;system("pause");return 0;
}
pl/0 程序
var m, n, r, q;
procedure gcd;
begin
while r#0 do
begin
q := m / n;
r := m - q * n;
m := n;
n := r;
end;
end;
begin
read(m);
read(n);
if m < n then
begin
r := m;
m := n;
n := r;
end;
begin
r:=1;
call gcd;
write(m);
end;
end.
輸出結果
#
#
using---->25
namespace---->25
std---->25
;------->41
int---->7
main---->1
(------->42
)------->43
const---->18
string---->25
str---->25
=------->38
hello---->25
;------->41
const---->18
string---->25
str2---->25
=------->38
world---->25
;------->41
string---->25
n_str---->25
;------->41
n_str---->25
=------->38
str---->25
;------->41
n_str---->25
+------->27
=------->38
str2---->25
;------->41
cout---->25
<------>33
<------>33
n_str---->25
<------>33
<------>33
endl---->25
;------->41
return---->17
0------>26
;------->41
總結
以上是生活随笔 為你收集整理的pl/0词法分析器 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。