C語言設(shè)計(jì)實(shí)現(xiàn)掃描器的自動(dòng)機(jī)的示例詳解
題目?jī)?nèi)容
內(nèi)容:
1.設(shè)計(jì)掃描器的自動(dòng)機(jī);
2.設(shè)計(jì)翻譯、生成Token的算法;
3.編寫代碼并上機(jī)調(diào)試運(yùn)行通過。
要求:
掃描器可識(shí)別的單詞包括:關(guān)鍵字、界符、標(biāo)識(shí)符和常整型數(shù)。
其中關(guān)鍵字表、界符表、標(biāo)識(shí)符表、常整數(shù)表如下:
關(guān)鍵字表K(1int 2void 3break 4float 5while 6do 7struct 8coust 9case 10for 11return 12if 13default 14else)
界符表 P(1 - 2 / 3 ( 4 ) 5 -- 6<= 7< 8+ 9* 10> 11= 12, 13; 14++ 15 { 16 } 17 ' 18 " )
標(biāo)識(shí)符表I (1 2 3 4 5 6 7 8 9 10 11 12 13 14)
常整數(shù)表C(1 2 3 4 5 6 7 8 9 10 11 12 13 14)
【輸入形式】
源程序文件。
【輸出形式】
(1)相應(yīng)單詞的Token序列;
(2)標(biāo)識(shí)符表,常數(shù)表。
【測(cè)試用例1】
輸入:x10=x+y1*120+10;
輸出:
Token序列:(I 1)(P 11)等等
標(biāo)識(shí)符表:x10 x y1
常數(shù)表:120 10
思路
題目中的輸出形式是:(1)相應(yīng)單詞的Token序列;(2)標(biāo)識(shí)符表,常數(shù)表。因此,我們可以在上述代碼中調(diào)整輸出的格式。
對(duì)于 Token 序列的輸出,我們可以將其格式化為如下形式:
Token序列:(<單詞種類>, <單詞內(nèi)容>)
例如:(KEYWORD, int)(IDENTIFIER, x)(DELIMITER, =)(INTEGER, 10)
對(duì)于標(biāo)識(shí)符表和常整數(shù)表的輸出,我們可以將其格式化為如下形式:
標(biāo)識(shí)符表: x y
常整數(shù)表: 10 20
為了實(shí)現(xiàn)這種輸出格式,我們可以在輸出 Token 序列之后,再輸出標(biāo)識(shí)符表和常整數(shù)表。
代碼
#include <stdio.h> #include <string.h> #include <ctype.h> // 定義單詞種類 typedef enum { KEYWORD, // 關(guān)鍵字 DELIMITER, // 界符 IDENTIFIER,// 標(biāo)識(shí)符 INTEGER // 常整型數(shù) } TokenType; // 關(guān)鍵字表 char *keywords[] = { "int", "void", "break", "float", "while", "do", "struct", "const", "case", "for", "return", "if", "default", "else" }; // 界符表 char delimiters[] = { '-', '/', '(', ')', '--', '<=', '<', '+', '*', '>', '=', ',', ';', '++', '{', '}', '\'', '"' }; // 標(biāo)識(shí)符表 char *identifiers[100]; int identifier_count = 0; // 常整數(shù)表 int integers[100]; int integer_count = 0; // Token 序列 struct Token { TokenType type; // 單詞種類 char *lexeme; // 單詞內(nèi)容 int value; // 單詞值 } tokens[100]; int token_count = 0; // 讀入的源程序 char source[100]; int source_pos = 0; // 讀入下一個(gè)字符 char get_char() { return source[source_pos++]; } // 跳過空白符 void skip_space() { while (isspace(source[source_pos])) source_pos++; } // 讀入單詞 void get_token() { skip_space(); char ch = get_char(); // 如果是字母,則讀入單詞 if (isalpha(ch)) { int lexeme_pos = 0; char lexeme[100]; while (isalpha(ch) || isdigit(ch)) { lexeme[lexeme_pos++] = ch; ch = get_char(); } lexeme[lexeme_pos] = '\0'; source_pos--; // 將最后讀入的非字母或數(shù)字字符放回去 // 判斷是否為關(guān)鍵字 for (int i = 0; i < 14; i++) { if (strcmp(keywords[i], lexeme) == 0) { tokens[token_count].type = KEYWORD; tokens[token_count].lexeme = lexeme; token_count++; return; } } // 如果不是關(guān)鍵字,則加入標(biāo)識(shí)符表 identifiers[identifier_count] = lexeme; tokens[token_count].type = IDENTIFIER; tokens[token_count].lexeme = lexeme; tokens[token_count].value = identifier_count; identifier_count++; token_count++; return; } // 如果是數(shù)字,則讀入常整數(shù) if (isdigit(ch)) { int value = 0; while (isdigit(ch)) { value = value * 10 + (ch - '0'); ch = get_char(); } source_pos--; // 將最后讀入的非數(shù)字字符放回去 // 加入常整數(shù)表 integers[integer_count] = value; tokens[token_count].type = INTEGER; tokens[token_count].value = value; integer_count++; token_count++; return; } // 如果是界符,則讀入界符 for (int i = 0; i < 18; i++) { if (delimiters[i] == ch) { // 加入 Token 序列 tokens[token_count].type = DELIMITER; tokens[token_count].lexeme = ch; token_count++; return; } } } int main() { // 讀入源程序 scanf("%s", source); // 讀入 Token 序列 while (source_pos < strlen(source)) { get_token(); } // 輸出 Token 序列 for (int i = 0; i < token_count; i++) { if (tokens[i].type == KEYWORD) { printf("(KEYWORD, %s)\n", tokens[i].lexeme); } else if (tokens[i].type == IDENTIFIER) { printf("(IDENTIFIER, %s)\n", tokens[i].lexeme); } else if (tokens[i].type == INTEGER) { printf("(INTEGER, %d)\n", tokens[i].value); } else if (tokens[i].type == DELIMITER) { printf("(DELIMITER, %c)\n", tokens[i].lexeme); } } // 輸出標(biāo)識(shí)符表 printf("\nIdentifier Table:\n"); for (int i = 0; i < identifier_count; i++) { printf("%s\n", identifiers[i]); } // 輸出常整數(shù)表 printf("\nInteger Table:\n"); for (int i = 0; i < integer_count; i++) { printf("%d\n", integers[i]); } return 0; }
到此這篇關(guān)于C語言設(shè)計(jì)實(shí)現(xiàn)掃描器的自動(dòng)機(jī)的示例詳解的文章就介紹到這了,更多相關(guān)C語言掃描器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++數(shù)據(jù)模型應(yīng)用在QML委托代理機(jī)制中
這篇文章主要介紹了在QML委托代理機(jī)制中使用C++數(shù)據(jù)模型,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08C語言實(shí)現(xiàn)餐飲結(jié)賬管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)餐飲結(jié)賬管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11C語言計(jì)算代碼執(zhí)行所耗CPU時(shí)鐘周期
本文給大家介紹的是使用C語言來計(jì)算代碼執(zhí)行所耗CPU時(shí)鐘周期的代碼,非常的簡(jiǎn)單實(shí)用,不過要依托于sync,有需要的小伙伴自己參考下吧。2015-03-03C++中Cbitmap,HBitmap,Bitmap區(qū)別及聯(lián)系
這篇文章主要介紹了C++中Cbitmap,HBitmap,Bitmap區(qū)別及聯(lián)系的相關(guān)資料,需要的朋友可以參考下2015-06-06