期貨量化軟件;赫茲量化國(guó)聯(lián)期貨極速版普拉特和分流場(chǎng)解析器
解析器采用運(yùn)算符優(yōu)先級(jí)
我們要研究的下一個(gè)解析器類型是優(yōu)先級(jí)解析器。 它們具有更緊湊的實(shí)現(xiàn),因?yàn)轭惙椒ú⒎腔谡Z(yǔ)法規(guī)則創(chuàng)建的(在這種情況下,每個(gè)規(guī)則都轉(zhuǎn)換為單獨(dú)的方法),而是采用更通用的形式,僅考慮運(yùn)算符的優(yōu)先級(jí)。
在 EBNF 語(yǔ)法說(shuō)明中,操作的優(yōu)先級(jí)已經(jīng)以隱式形式出現(xiàn):其規(guī)則執(zhí)行從低優(yōu)先級(jí)操作到高優(yōu)先級(jí)操作,直至終結(jié)實(shí)體 — 常量和變量。 這是因?yàn)樵跊](méi)有顯式括號(hào)分組的情況下,優(yōu)先級(jí)判定應(yīng)是操作執(zhí)行的順序。 例如,乘法運(yùn)算的優(yōu)先級(jí)高于加法的優(yōu)先級(jí)。 但是一元減號(hào)優(yōu)先于乘法。 語(yǔ)法樹元素越靠近根部(整個(gè)表達(dá)式),對(duì)其進(jìn)行評(píng)估越靠后。
為了實(shí)現(xiàn)解析器,我們需要兩個(gè)表,每張表的數(shù)值與每個(gè)操作的優(yōu)先級(jí)相對(duì)應(yīng)。 值越高,優(yōu)先級(jí)越高。
我們有兩張表,因?yàn)橐辉投\(yùn)算會(huì)在算法中邏輯上分開。 實(shí)際上,我們不僅在討論操作,且在更廣泛地討論有關(guān)在表達(dá)式中如何找到可作為前綴和后綴的符號(hào)(Wikipedia 上有更多關(guān)于操作符類型的信息)。
顧名思義,前綴是操作數(shù)之前的符號(hào)(例如,“!var” 表達(dá)式中的 “!”),而中綴是操作數(shù)之間的字符(例如,表達(dá)式 ”a + b“ 中的 ‘+’)。 還有一些后綴(例如,增量運(yùn)算符中的一對(duì) “+”,在 MQL 中也可以用 — “i++”),但是我們?cè)诒磉_(dá)式中沒(méi)有用到它們,因此我們先不考慮它們。
除了一元運(yùn)算符 '!','-','+' 外,前綴還可以是一個(gè)開始括號(hào) '(' — 表示分組的開頭;字母或下劃線 — 表示標(biāo)識(shí)符的開頭;以及數(shù)字或句點(diǎn) “.” — 表示數(shù)字常數(shù)的開頭。
我們講述 ExpressionPrecedence 類中的表,它繼承自某些基于優(yōu)先級(jí)的解析器類。 所有這些解析器將與 Promise 一起操作。
?class ExpressionPrecedence: public AbstractExpressionProcessor<Promise *> ?{ ? ?protected: ? ? ?static uchar prefixes[128]; ? ? ?static uchar infixes[128]; ? ? ? ? ? ?static ExpressionPrecedence epinit; ? ? ? ? ? ?static void initPrecedence() ? ? ?{ ? ? ? ?// 分組 ? ? ? ?prefixes['('] = 9; ? ? ? ? ?// 一元運(yùn)算符 ? ? ? ?prefixes['+'] = 9; ? ? ? ?prefixes['-'] = 9; ? ? ? ?prefixes['!'] = 9; ? ? ? ? ? ? ? ?// 標(biāo)識(shí)符 ? ? ? ?prefixes['_'] = 9; ? ? ? ?for(uchar c = 'a'; c <= 'z'; c++) ? ? ? ?{ ? ? ? ? ?prefixes[c] = 9; ? ? ? ?} ? ? ? ? ? ? ? ?// 數(shù)字 ? ? ? ?prefixes['.'] = 9; ? ? ? ?for(uchar c = '0'; c <= '9'; c++) ? ? ? ?{ ? ? ? ? ?prefixes[c] = 9; ? ? ? ?} ? ? ? ? ? ? ? ?// 運(yùn)算符 ? ? ? ?// infixes['('] = 9; // 此處不將括號(hào)用作“函數(shù)調(diào)用”運(yùn)算符 ? ? ? ?infixes['*'] = 8; ? ? ? ?infixes['/'] = 8; ? ? ? ?infixes['%'] = 8; ? ? ? ?infixes['+'] = 7; ? ? ? ?infixes['-'] = 7; ? ? ? ?infixes['>'] = 6; ? ? ? ?infixes['<'] = 6; ? ? ? ?infixes['='] = 5; ? ? ? ?infixes['!'] = 5; ? ? ? ?infixes['&'] = 4; ? ? ? ?infixes['|'] = 4; ? ? ? ?infixes['?'] = 3; ? ? ? ?infixes[':'] = 2; ? ? ? ?infixes[','] = 1; // 參數(shù)列表定界符 ? ? ?} ? ? ? ?ExpressionPrecedence(const bool init) ? ? ?{ ? ? ? ?initPrecedence(); ? ? ?} ? ? ?public: ? ? ?ExpressionPrecedence(const string vars = NULL): AbstractExpressionProcessor(vars) {} ? ? ?ExpressionPrecedence(VariableTable &vt): AbstractExpressionProcessor(vt) {} ?}; ? ?static uchar ExpressionPrecedence::prefixes[128] = {0}; ?static uchar ExpressionPrecedence::infixes[128] = {0}; ?static ExpressionPrecedence ExpressionPrecedence::epinit(true);