二、截取單元指令 (Tokenize)
因為程序比較簡單,只有 2 種單元指令:NumToken 和 OpToken。
我定義了一個基本類,叫做 Token,然後 NumToken 和 OpToken 繼承了該基本類。
Class Token:什麼也沒有,暫時是空殼子。
internal abstract class Token
{
}
Class NumToken: 表述一個數。
internal sealed class NumToken : Token
{
public double Value { get; }
}
Class OpToken: 表述一個運算符。
internal sealed class OpToken : Token
{
public Op Value { get; }
public Prioirty Prioirty { get; }
}
Op 和 Priority 是 2 個 enum:
internal enum Op : int
{
Plus = '+',
Minus = '-',
Multiply = '*',
Divide = '/'
}
internal enum Prioirty
{
Lv2 = 2,
Lv1 = 1,
Lv0 = 0
}
截取的算法相對來說很簡單,是由 Tokenizer 類來實現的。這個類是 internal sealed,因為外界不需要知道它的存在。Tokenizer 會被 Intepreter 類所使用。
internal sealed class Tokenizer
{
public Token[] Parse(string value);
}
在 Parse 函數裡面,掃描輸入字符串,從第一個字符開始,一直到最後一個字符。空白字符會被忽略掉。
我們定義了個緩沖 buffer,用來存儲已經掃描到的數字。若是遇到了一個非數字,就把緩沖區所有的存儲的字節轉變成 double 類型,然後保存下來。值得注意的是,對小數點的處理。若是緩沖區裡面已經存在了一個小數點,遇到一個新的小數點就應該拋出錯誤。
每當掃描到一個操作符,比如 +, –, *, /,就把他們當作一個操作符存儲起來。這裡要注意的是,數字的正負號其實是一個一元操作符,是何數字分開保存的。
遇到其他沒有定義的字符,就直接拋出錯誤。