首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

手把手教你寫腳本引擎(二):命令式腳本引擎與外掛架構

     編輯:關於C++

系列第二篇實作最簡單的命令式腳本引擎:僅含指令、標籤、跳轉,類似組合語言但可讀性佳。建立完整引擎五大組件:程式碼資料結構、執行時環境、語法分析器、外掛系統、虛擬機。

語言語法定義

  • <值>:整數、浮點數、字串、名稱
  • <名>:字母/底線開頭的識別子
  • <名>: 標籤定義
  • goto <名>:無條件跳轉
  • set <名> <值>:變數賦值(自動建立)
  • opcode <名> <值> <值>:add/minus/mul/div/idiv/mod 運算存結果
  • if <值> [opcode <值>] goto <名>:條件跳轉(比較運算子:is/is_not/less_than/...)
  • exit:結束執行
  • 其他指令 → 轉交外掛處理

範例程式:質數判斷

write "請輸入一個數字:"
read Number
if Number less_then 2 goto FAIL
if Number is 2 goto SUCCESS
set Divisor 2
LOOP_BEGIN:
if Number is Divisor goto SUCCESS
mod Remainder Number Divisor
if Remainder is 0 goto FAIL
add Divisor Divisor 1
goto LOOP_BEGIN
SUCCESS:
writeln Number "是質數。"
exit
FAIL:
writeln Number "不是質數。"

詞法分析實作

支援字串常數,不能單純用空格分割。採用逐字元掃描函數:

int GetInt(wchar_t*& Input);
int GetReal(wchar_t*& Input);
int GetName(wchar_t*& Input);
int GetString(wchar_t*& Input);
int GetColon(wchar_t*& Input);
int GetSpace(wchar_t*& Input);

解析順序:GetSpace → GetColon → GetString → GetName → GetReal → GetInt(整數需在浮點數之後避免誤吞)。

語法分析與資料結構

enum LexerType { ltString, ltName };
struct LexerToken { LexerType Type; wstring Token; };
struct Command { wstring Name; vector Parameters; };

vector FCommands;
map FLabels;  // 標籤 → 指令索引

解析兩階段:逐行切分 Token → 辨識標籤/指令填入表格。

虛擬機執行流程

指令指標 IP 循環取指令 → 依指令名分派執行 → 更新 IP。變數儲存於 Environment(名稱→值映射)。

外掛系統:責任鏈模式

class Plugin {
public:
    virtual PluginStatus Execute(const Command& cmd, Environment& env, wstring& errMsg) = 0;
};
vector FPlugins;

引擎遇到未知指令依序詢問外掛:成功→繼續、失敗→停止報錯、棄權→詢問下一個。全棄權則報「無效指令」。

原始碼結構

  • Lexer.h/cpp:詞法分析器
  • ScriptCommand.h/cpp:腳本引擎核心
  • Main.cpp:主程式(讀取 SE_02.txt 執行)

下篇預告

高階語言腳本引擎:支援陣列、函數、弱型別的完整實作。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved