2012-10-25 52 views

回答

0

你所需要的 - 如果你想自己做 - 在它的後面解釋表達代碼Scanner (also known as Lexer) + Parser。或者,您可以找到一個第三方庫,其功能與JavaScript eval(string)功能類似。

請看看here,它描述了一個遞歸下降解析器。這個例子寫在C,但你應該能夠很容易地適應它C#一旦你有了這篇文章中描述的想法。

這聽起來不那麼複雜,尤其是如果您的操作員數量有限時。

好處是您可以完全控制要執行的表達式(以防止惡意代碼被您的網站的最終用戶注入)。

0

您將需要實現(或查找第三方來源)表達式分析器。這是不是這是一件小事。

4
operators as strings

回答用戶https://stackoverflow.com/users/1670022/matt-crouch

「如果你需要的是簡單的算術題,做這個

DataTable temp = new DataTable(); 
    Console.WriteLine(temp.Compute("15/3",string.Empty)); 

編輯:一點點的更多信息檢查出Expression屬性的MSDN文檔System.Data.DataColumn類。「Expression Syntax」中的內容列出了除算術運算符外可以使用的命令列表(例如,IIF,LEN等)。「

+0

+1,今天學習的新技巧 –

5

.NET沒有用於評估任意字符串的內置函數。但是,一個名爲NCalc的開源.NET庫的確如此。

NCalc是.NET中的數學表達式求值器。 NCalc可以解析 任何表達式並評估結果,包括靜態或動態 參數和自定義函數。

+0

'驚訝你的建議不容易滲透到頂部。我最好盡我所能(+1),因爲我在我自己的「宣言」 – mjv

3

這個問題有兩種主要方法,每種都有一些變化,如各種答案中所示。

  • 選項A:找一個現有的數學expresssion評估
  • 選項B:寫自己的解析器和邏輯來計算結果

之前進入這個一些細節,是適當的強調解釋任意數學表達式對於任何除「玩具」語法之外的任何表達式語法(例如僅接受一個或兩個算術運算並且不允許括號等)的表達語法都不是一項簡單的任務

瞭解這樣的任務是微不足道的,並且承認畢竟,解釋平均複雜度的算術表達式對於各種應用程序來說是相對反覆的需求[因此應該有可用的成熟解決方案],所以嘗試和選擇「選項A」。
因此,我會第二個傑德的建議現成的表達式評估器,如NCalc

這可能是有用然而花時間和了解各種概念和分析相關的方法和解釋算術表達式,就好像一個人要鞭打,建立自己的實現。

關鍵概念是formal grammar。評估者接受的算術表達式必須遵循一系列規則,例如允許的算術運算列表。例如,評估者是否支持三角函數,或者如果是這樣的話,是否還會包含atan2()。這些規則還指出構成操作數的是什麼,例如,它將被允許輸入與45位一樣大的數值。等等。關鍵是所有這些規則都是用語法形式化的。

典型地,語法適用於令牌先前已經從原始輸入文本萃取。基本上在這個過程中的某個時候,一些邏輯需要分析輸入字符串逐個字符,並確定哪些字符序列一起。例如在123 + 45/9.3表達式中,令牌是整數值123plus運算符,整數值45division運算符和最後9.3實際值。識別令牌並將它們與令牌類型相關聯的任務是作業lexer。詞法分析器可以根據語法建立自己的語法(這是一種「令牌」是單個字符的語法,與算術表達式分析器的語法相反,這種語法是由詞法分析器生成的短字符串。)

順便說一句,語法用於定義除算術表達式之外的許多其他事物計算機語言遵循[相當複雜的]語法,但是引入域特定語言 aka DSL支持計算機應用程序的各種特徵是比較常見的。

對於非常簡單的語法,可以從頭開始編寫相應的詞法分析器和分析器。但遲早,語法可能會變得複雜,以至於手寫這些模塊變得挑剔,容易出錯,並且可能更難以閱讀。因此,存在Lexer and Parser Generators,這是獨立的程序,它從規則列表中產生詞法分析器和分析器的代碼(以特定的編程語言,例如C,Java或C#)(用對生成器特定的語法表示)發電機傾向於使用類似的語法,鬆散地基於BNF)。

當使用這樣的詞法/解析器生成器,在工作在多個步驟完成的:
- 第一個寫語法的定義(在特定的發電機語言/語法)
- 一個運行此語法通過發電機。
- 人們經常重複上述兩個步驟多次,因爲編寫一個語法是一個嚴格的練習:生成器會抱怨很多可能會寫入語法的可能的歧義。
- 最終發生器產生一個源文件(在期望的目標語言,諸如C#等)
- 這個源被包括在整個項目
- 在項目可以調用源暴露的功能的其它的源文件由發生器產生的文件和/或對應於在解析期間識別的各種模式的一些邏輯可以容易地嵌入發生器產生的代碼中。
- 然後可以像往常一樣構建項目,就好像解析器和詞法分析器是手寫的。

這就是關於它的一個高達20,000英尺高的過程與正式語法和代碼生成器一起使用。
可在此link處找到解析器生成器(也稱爲編譯器編譯器)列表。對於C#中的簡單工作,我也想提到Irony。仔細閱讀這些網站,以便更好地感受這些概念,即使目前沒有成爲實踐者的意圖。
至於說,我想強調的是對於這個特定的應用,一個現成的算術評估可能是更好的方法。這些主要缺點是

  • 一些限制,以允許表達式語法是什麼(或者允許的語法過於侷限:你還需要說STDDEV()或過於寬泛:你不希望你的用戶使用觸發功能。隨着更多成熟的評估,會有某種形式的配置/擴展功能,其允許處理這一問題。
  • 這樣的第三方模塊的學習曲線。我希望很多人應該是比較「即插即用「