編譯原理頭歌實驗:詞法分析程序設計與實現(C語言版)

編譯原理頭歌實驗:詞法分析程序設計與實現(C語言版)

1.實驗描述

任務描述

本關任務:加深對詞法分析器的工作過程的理解;加強對詞法分析方法的掌握;能夠采用一種編程語言實現簡單的詞法分析程序;能夠使用自己編寫的分析程序對簡單的程序段進行詞法分析。

編程要求

根據提示,在右側編輯器補充代碼標示符、數字符及其他字符符號的識別程序后,點擊評測運行程序,系統會自動進行結果對比。

測試說明

平臺會對你編寫的代碼進行測試:

測試輸入:

using namespace std; int main() {
int year;
cout << “hello” << endl;
return 0; }

2.實驗操作提示

2.1定義目標語言的可用符號表和構詞規則。

我們需要對五種單詞符號進行識別分析,這里將單詞符號分為三大塊進行識別。首先判斷字符是否為關鍵字或者標識符,并與已定義好的關鍵字進行比較,從而判斷為關鍵字或者標識符;然后是數字的識別;最后是其他字符的判斷,它們被一一定義好的判斷進行識別,這樣所有的字符便被識別出來了。標示符和關鍵字的判斷

if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))  //可能是標示符或者關鍵字

字符與關鍵字的區別通過對比得出:

if (strcmp(token, rwtab1[n]) == 0){syn = 2;break;}else if (strcmp(token, rwtab[n]) == 0) {syn = 1;break;}}

對于數字的識別:

else if ((ch >= '0' && ch <= '9'))  //數字 

其他字符的識別,他們被一一定義進行識別:

else switch (ch)   //其他字符 {case'<':m = 0; token[m++] = ch;ch = prog[p++];if (ch == '>'){syn = 4;token[m++] = ch;}else if (ch == '='){syn = 4;token[m++] = ch;}else{syn = 4;p--;}break;case'>':m = 0; token[m++] = ch;ch = prog[p++];if (ch == '='){syn = 4;token[m++] = ch;}else{syn = 4;p--;}break;case':':m = 0; token[m++] = ch;ch = prog[p++];if (ch == '='){syn = 4;token[m++] = ch;}else{syn = 4;p--;}break;case'*':syn = 4; token[0] = ch; break;case'/':syn = 4; token[0] = ch; break;case'+':syn = 4; token[0] = ch; break;case'-':syn = 4; token[0] = ch; break;case'=':syn = 4; token[0] = ch; break;case';':syn = 5; token[0] = ch; break;case',':syn = 5; token[0] = ch; break;case'(':syn = 5; token[0] = ch; break;case')':syn = 5; token[0] = ch; break;case'{':syn = 5; token[0] = ch; break;case'}':syn = 5; token[0] = ch; break;case'#':syn = 0; token[0] = ch; break;case'\n':syn = -2; break;default: syn = -1; break;}
}

依次讀入源程序符號,對源程序進行單詞切分和識別,直到源程序結束。
字符的輸入我們使用cin.get() 獲取,并切分保存在 prog中:

p = 0;row = 1;cout << "Please input string:" << endl;do{cin.get(ch);prog[p++] = ch;} while (ch != '#');p = 0; 

對正確的單詞,按照它的種別以<種別碼,值>的形式保存在符號表中;

對不正確的單詞,做出錯誤處理。
單詞識別后,我們對返回的符號按3,4的規則進行輸出:

{scaner();switch (syn){case 0: break;case 3: cout << "(" << syn << "," << sum << ")" << endl; break;case -1: cout << "Error in row " << row << "!" << endl; break;case -2: row = row++; break;default: cout << "(" << syn << "," << token << ")" << endl; break;}} while (syn != 0); 

3.實驗代碼展示

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
char prog[1000], token[20];
char ch;
int syn, p, m = 0, n, row = 1, sum = 0;
// 擴充關鍵字表
const char* rwtab[10] = { "if","int","for","while","do","return","break","continue", "using", "namespace" };
const char* rwtab1[8] = { "main","a","b","c","d","e","f","g" };void scaner()
{// 初始化token數組for (n = 0; n < 20; n++) token[n] = '\0';// 跳過空白字符while (p < strlen(prog) && (prog[p] == ' ' || prog[p] == '\t' || prog[p] == '\n')){if (prog[p] == '\n')row++;p++;}if (p >= strlen(prog)){syn = 0;return;}ch = prog[p++];// 進行標示符或者關鍵字的識別if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')){m = 0;while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')){token[m++] = ch;if (p >= strlen(prog))break;ch = prog[p++];}token[m] = '\0';if (p < strlen(prog))p--;syn = 2;for (n = 0; n < 10; n++) // 更新關鍵字表長度{if (strcmp(token, rwtab[n]) == 0){syn = 1;break;}}}// 進行數字的識別else if (ch >= '0' && ch <= '9'){sum = 0;while (ch >= '0' && ch <= '9'){sum = sum * 10 + (ch - '0');if (p >= strlen(prog))break;ch = prog[p++];}if (p < strlen(prog))p--;syn = 3;}// 進行其他字符的識別else{switch (ch){case '<':m = 0;token[m++] = ch;if (p < strlen(prog) && prog[p] == '<'){token[m++] = prog[p++];syn = 4;}else{syn = 4;p--;}break;case '>':m = 0;token[m++] = ch;if (p < strlen(prog) && prog[p] == '='){token[m++] = prog[p++];syn = 4;}else{syn = 4;p--;}break;case ':':m = 0;token[m++] = ch;if (p < strlen(prog) && prog[p] == '='){token[m++] = prog[p++];syn = 4;}else{syn = 4;p--;}break;case '*':syn = 4;token[0] = ch;break;case '/':syn = 4;token[0] = ch;if (p < strlen(prog) && prog[p] == '/') {token[1] = '/';syn = 5; // 注釋符號作為界符處理p++;}break;case '+':syn = 4;token[0] = ch;break;case '-':syn = 4;token[0] = ch;break;case '=':syn = 4;token[0] = ch;break;case ';':syn = 5;token[0] = ch;break;case ',':syn = 5;token[0] = ch;break;case '(':syn = 5;token[0] = ch;break;case ')':syn = 5;token[0] = ch;break;case '{':syn = 5;token[0] = ch;break;case '}':syn = 5;token[0] = ch;break;case '#':syn = 0;token[0] = ch;break;case '"':syn = 5;token[0] = ch;break;default:syn = -1;break;}}
}int main()
{// 輸入p = 0;cout << "Please input string:" << endl;do{cin.get(ch);prog[p++] = ch;} while (ch != '#');prog[p] = '\0';p = 0;// 輸出do{scaner();switch (syn){case 0:break;case 3:cout << "(" << syn << "," << sum << ")" << endl;break;case -1:cout << "Error in row " << row << "!" << endl;break;default:cout << "(" << syn << "," << token << ")" << endl;break;}} while (syn != 0);return 0;
}    

在這里插入圖片描述

這個詞法分析器通過逐字符讀取輸入,根據字符的類型和上下文規則,識別出關鍵字、標識符、數字、運算符和分隔符。它能正確處理簡單的 C++ 代碼段,并輸出每個記號的類型和內容。程序設計清晰,邏輯分明,適合學習詞法分析的基本原理。

希望這個講解能幫助你深入理解代碼的實現過程!如果有疑問,歡迎評論區交流!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82150.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82150.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82150.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SQL常用操作大全:復制表、跨庫查詢、刪除重復數據

大家好&#xff0c;歡迎來到程序視點&#xff01;我是你們的老朋友.小二&#xff01; SQL常用操作精華總結 表結構與數據操作 復制表結構&#xff1a; SELECT * INTO b FROM a WHERE 1<>1 (SQL Server專用) SELECT TOP 0 * INTO b FROM a (更通用) 拷貝表數據&#…

課外活動:簡單了解原生測試框架Unittest前置后置的邏輯

簡單了解原生測試框架Unittest前置后置的邏輯 一、測試框架執行順序解析 1.1 基礎執行流程 import unittestclass A(unittest.TestCase):classmethoddef setUpClass(cls):print(f"【CLASS START】{cls.__name__}")def setUp(self):print(f"【TEST START】{se…

學習設計模式《八》——原型模式

一、基礎概念 原型模式的本質是【克隆生成對象】&#xff1b; 原型模式的定義&#xff1a;用原型實例指定創建對象的種類&#xff0c;并通過拷貝這些原型創建新的對象 。 原型模式的功能&#xff1a; 1、通過克隆來創建新的對象實例&#xff1b; 2、為克隆出來的新對象實例復制…

olmOCR - PDF文檔處理工具包

文章目錄 一、關于 olmOCR相關資源包含內容團隊 二、安裝三、本地使用示例查看結果多節點/集群使用管道完整文檔 一、關于 olmOCR olmOCR 是用于訓練語言模型處理PDF文檔的工具包&#xff0c;支持大規模PDF文本解析和轉換。 相關資源 源碼&#xff1a;https://github.com/all…

Android開發補充內容

Android開發補充內容 fragment通信生命周期 Okhttp基本使用websocket Retrofit基本使用 RxJava基本使用定時任務 Hilt基本使用進階使用例子 組件庫Material ComponentsJetpack Compose fragment 通信 fragment于activity通信的一種原生方法是使用Bundle&#xff1a; Bundle …

隱私計算框架FATE二次開發心得整理(工業場景實踐)

文章目錄 版本介紹隱私計算介紹前言FATE架構總體架構FateBoard架構前端架構后端架構 FateClient架構創建DAG方式DAG生成任務管理python SDK方式 FateFlow架構Eggroll架構FATE算法架構Cpn層FATE ML層 組件新增流程新增組件流程新增算法流程 版本介紹 WeBank的FATE開源版本 2.2.…

AI驅動的制造工藝:系統化探索與創新

DeepSeek 技術全景 在當今 AI 技術蓬勃發展的時代,DeepSeek 已成為該領域中一顆耀眼的明星。自 2023 年 7 月 17 日成立以來,這家由知名私募巨頭幻方量化孕育而生的公司,迅速在 AI 領域嶄露頭角 。DeepSeek 的目標是開發頂尖的大語言模型(LLM),并利用數據蒸餾技術打造更精…

【嵌入式開發-LCD】

嵌入式開發-LCD ■ LCD簡介 ■ LCD簡介

java反射(2)

package 反射;import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays;public class demo {public static void main(String[] args) throws Exception {// 通過類的全限定名獲取對應的 Class 對象…

使用 Cesium 構建 3D 地圖應用的實踐

CesiumJS 是一個功能強大的開源 JavaScript 庫&#xff0c;能夠幫助開發者快速構建高性能、高精度的 3D 地球和地圖應用 。本文將介紹如何使用 Cesium 構建一個基本的 3D 地圖應用&#xff0c;并加載自定義的 3D Tiles 模型。 初始化 Cesium Viewer 首先&#xff0c;在 Vue 的…

結合Splash與Scrapy:高效爬取動態JavaScript網站

在當今的Web開發中&#xff0c;JavaScript的廣泛應用使得許多網站的內容無法通過傳統的請求-響應模式直接獲取。為了解決這個問題&#xff0c;Scrapy開發者經常需要集成像Splash這樣的JavaScript渲染引擎。本文將詳細介紹Splash JS引擎的工作原理&#xff0c;并探討如何將其與S…

企業級可觀測性實現:OpenObserve云原生平臺的本地化部署與遠程訪問解析

文章目錄 前言1. 安裝Docker2. 創建并啟動OpenObserve容器3. 本地訪問測試4. 公網訪問本地部署的OpenObserve4.1 內網穿透工具安裝4.2 創建公網地址 5. 配置固定公網地址 前言 嘿&#xff0c;各位小伙伴們&#xff0c;今天要給大家揭秘一個在云原生領域里橫掃千軍的秘密法寶—…

將本地項目提交到新建的git倉庫

方式一: # 登錄git&#xff0c;新建git倉庫和指定的分支&#xff0c;如master、dev# 下載代碼&#xff0c;默認下載master分支 git clone http://10.*.*.67/performance_library/pfme-*.git # 切換到想要提交代碼的dev分支 git checkout dev# 添加想要提交的文件 git add .#…

.NET平臺用C#在PDF中創建可交互的表單域(Form Field)

在日常辦公系統開發中&#xff0c;涉及 PDF 處理相關的開發時&#xff0c;生成可填寫的 PDF 表單是一種常見需求&#xff0c;例如員工信息登記表、用戶注冊表、問卷調查或協議確認頁等。與靜態 PDF 不同&#xff0c;帶有**表單域&#xff08;Form Field&#xff09;**的文檔支持…

在macOS上安裝windows系統

使用Boot Camp 1. 準備工作&#xff1a;確認Mac滿足Boot Camp系統要求&#xff0c;準備好Windows安裝光盤或ISO映像文件&#xff0c;以及一個至少8GB的空白USB閃存驅動器用于保存驅動程序。 2. 打開Boot Camp助理&#xff1a;在“應用程序”文件夾的“實用工具”中找到“Boot…

683SJBH基于J2EE的廣州旅游管理系統

第1章  緒論 課題背景 自互聯網internet成為一種革命性的大眾媒體以來&#xff0c;其發展速度之快令人驚嘆。而作為世界最大朝陽產業的旅游&#xff0c;當它與電子商務這一新興模式相結合時&#xff0c;其潛藏的商業價值表露無遺。根據CNN&#xff08;美國有線電視新聞網&…

前端面試每日三題 - Day 27

這是我為準備前端/全棧開發工程師面試整理的第27天每日三題練習&#xff0c;涵蓋了&#xff1a; CSS選擇器的優先級與權重計算機制Angular中的依賴注入&#xff08;Dependency Injection&#xff09;機制設計一個支持實時協作編輯&#xff08;如Google Docs&#xff09;的前端…

PostgreSQL數據庫操作SQL

數據庫操作SQL 創建 創建數據庫 create database db_test;創建并指定相關參數 with owner : 所有者encoding : 編碼connection limit &#xff1a;連接限制 create database db_test1 with owner postgresencoding utf-8connection limit 100;修改 修改數據庫名稱 renam…

JSP HTTP 狀態碼詳解

JSP HTTP 狀態碼詳解 引言 HTTP 狀態碼是 HTTP 協議的一部分,用于表示客戶端與服務器之間請求與響應的狀態。在 JavaServer Pages (JSP) 技術中,HTTP 狀態碼同樣扮演著重要的角色。本文將詳細解析 JSP 中的 HTTP 狀態碼,幫助開發者更好地理解和應用這些狀態碼。 HTTP 狀態…

文件一鍵解密軟件工具(支持pdf、word、excel、ppt、rar、zip格式文件)

一鍵解密解鎖神器支持解密pdf、doc、docx、xls、xlsx、ppt、pptx、rar、zip格式文件&#xff0c;Excel表格、Word文檔、PPT演示、RAR、ZIP壓縮包、PDF文檔一鍵輕松解密&#xff01;簡單/高效/安全。這款軟件由密碼帝官方提供&#xff0c;確保了其合法性和安全性&#xff0c;用戶…