2013-03-08 115 views
1

我打算構建一個命令行工具。 我希望用戶輸入一個文本/字符串(函數/命令)。 然後,我的工具將這些字符串轉換爲C++函數/變量。如何將輸入字符串轉換爲函數()

[他們會跑我的自定義數據類型,我自己的函數,而不是運行系統功能]

例: 用戶類型

>> myVar = c(123,456,789) 

我的工具就知道myVar是變量名。和c(123,456,789)integer的數組。並且它這些字符串轉換爲這樣的事情:

int myVar[] = {123,456,789}; 

和用戶可以調用一個函數太:

輸入:

>> myPrintf(myVar[0]); 

輸出

<< 123 

而且我的解決方案:我會BUIL一類,這可能是這樣的:

public class cVariable 
{ 
    public string varName; // the variable name 
    private varType; // the variable data-type 
    public string varData; // the value of this variable 
} 

而且我會用if/else報表就知道我必須要運行的數據類型/功能。

但我認爲這種方式並不好。

+1

您正在嘗試構建編譯器。祝你好運。 – SLaks 2013-03-08 02:10:53

+0

考慮使用LLVM。 – SLaks 2013-03-08 02:11:22

+0

你唯一真正的問題似乎是「如何將輸入字符串轉換爲函數()?」的標題。我建議'boost :: spirit'庫 - 這對您來說學習會有挑戰性,但是一旦您瞭解它,您就可以更輕鬆,更進一步地改進您的程序。如果你想快速開始,使用正則表達式可以幫助你測試賦值和函數調用,提取參數值等等。更基本的,你可以使用'sscanf()'。 「我認爲這種方式根本不好」 - 如果你解釋你的問題,人們可以發表評論。最明顯的評論是:使用ruby/perl/etc。 – 2013-03-08 02:13:08

回答

3

摘要:這可能比看起來更難。如果你有一小組案例,並且你希望今晚有一些工作(這主要是一個學習練習),那麼你可以簡單地使用你的第一種方法。

從您的問題中,您似乎想要創建自定義語言,解釋該語言並將其綁定到編譯後的二進制文件。總的來說,這是一項巨大的任務。如果您縮小範圍,您可能會得到更好的答案或結果。

如果您熟悉下列主題,你將有多少選擇提供給您的一個想法:

  • 編譯&鏈接
    • 動態鏈接
  • 思考
  • 腳本和解釋語言
    • 語言綁定
  • 代碼生成

對於你的程序有自己的知識結構和標識語言需要一個稱爲反射功能。標準C++沒有這個功能(而許多其他功能)。在編譯代碼時,不再有函數,類型或參數的字符串標識符。

見的在反射樣行爲的討論以下問題C/C++:How can I add reflection to a C++ application?

(對於動態鏈接約定存在C和C++,其在編譯的二進制位置提供從串的映射,但這可能不是實現你想要的最直接的方式。)

這聽起來像你想要的是建立一個解釋的語言,具有綁定到您的原始源代碼。如果你有一組非常孤立的案例,你可以考慮使用預處理技巧。 (上面的鏈接問題是指Qt的實現以及Boost工具。)

如果您願意使用現有的腳本語言,您可以研究從所述語言生成的C++代碼綁定。以下是Python的一些資源,例如:http://wiki.python.org/moin/IntegratingPythonWithOtherLanguages

+0

感謝您的關鍵字他們真的很有幫助。我對反射,動態鏈接......我不太瞭解,我想我現在必須對它們進行研究。謝謝 – hungdoan 2013-03-08 06:41:33

2

如果你真的打算做一些相對完整的事情,編寫自己的語言是一項相當艱鉅的任務。數千行代碼絕對有可能。在我30多年的專業和愛好生活中,我參與了各種形式的這種工作 - 從編寫一個調試器或類似的命令的簡單解析器到相當好的工作「微型基本」解釋器和一個小型Lisp解釋器。我也製作了很多「僞語言」,其中一個文本文件被用作程序的輸入,但它不是一個完整的編程語言 - 只有有限的一組變量。

我做過的很多事情是「表驅動編程」,其中實際的「代碼」以表格的形式嵌入到程序中。

在所有這些中,存在各種形式的「我有一些輸入/數據,我想將其轉化爲與其他對象相關的動作」。

正如你所描述的那樣,基本機制是將某些數據結構中的名稱和其他數據(如類型)存儲起來。 std::map<std::string, cVariable>將是一種相對容易地從名稱(字符串)檢索數據到該名稱變量的方法。

你可以明確地爲功能做同樣的事情。你當然也可以通過某種方式將參數傳遞給函數。到底你如何解決這個問題是每個語言都必須解決的問題,通常它最終會成爲某種「堆棧」。

你當然可以有一個map<std::string, function>從一個名稱轉換爲一個函數 - 函數定義可能包含一些關於該函數參數的數量和類型的信息。

對於「內置」的功能,你還可以有一個類型的argc, argv[]類型的方法,其中的參數作爲cVariable傳遞[其中一個選項是constantexpression],允許myPrint(myVar[0] + 100),這當然不是真正的變量,但將變量內容的結果添加到常量中。

如果你還沒有寫過類似帶變量計算器的東西,那可能是一個很好的起點。

許多「腳本」類型語言都有一個「多態」變量 - 也就是說,該值可以用作數字或字符串,而不需要實際要求轉換變量。

0

爲標題「一個字符串轉換爲函數()」,你可以用函數指針實現這一點:

int (*p)(char*,...) = printf; 

使用函數指針:

根據賦值函數調用函數:

char* str = "hello function pointer"; 
p("say %s", str); 

但這僅僅是你的問題的一半,首先你需要做一個詞彙更新的時候通知解析您的輸入和acording定義的規則確定什麼是一個令牌(構成命令行工具語言的符號),如DIGIT,BRACKETS,ASSIGNMENTS等。然後,您需要一個語法分析器,爲命令中的語法含義設置規則。這基本上是用狀態機完成的,但是這是一項複雜的任務,我認爲你不想自己實現它?請看FlexBisson工具來自動生成解析器。

這給你一個通用命令行工具的一般解決方案,它解釋你想要的任何語言。如果語法很簡單,你可以自己做一個解析器,也許有一些正則表達式庫。

相關問題