瀏覽代碼

Further optimized deep code in the scanning engine using a jump table to replace a collection of if/else logic.

Updated some of the related code using more modern and/or correct coding practices.


git-svn-id: https://svn.microneil.com/svn/SNFMulti/trunk@52 dc71a809-1921-45c4-985c-09c81d0142d9
wx
madscientist 11 年之前
父節點
當前提交
3613b43c5d
共有 2 個檔案被更改,包括 283 行新增288 行删除
  1. 251
    279
      snf_engine.cpp
  2. 32
    9
      snf_engine.hpp

+ 251
- 279
snf_engine.cpp 查看文件

@@ -217,38 +217,250 @@ void TokenMatrix::FlipEndian() {
// Evaluator Implementations //////////////////////////////////////////////////////////////

// 20030216 _M Optimization conversions

inline int Evaluator::i_lower() { return myEvaluationMatrix->i_lower; }
inline bool Evaluator::i_isDigit() { return myEvaluationMatrix->i_isDigit; }
inline bool Evaluator::i_isSpace() { return myEvaluationMatrix->i_isSpace; }
inline bool Evaluator::i_isAlpha() { return myEvaluationMatrix->i_isAlpha; }
// 20140119 _M Deprecated by jump table in evaluator
// inline int Evaluator::i_lower() { return myEvaluationMatrix->i_lower; }
// inline bool Evaluator::i_isDigit() { return myEvaluationMatrix->i_isDigit; }
// inline bool Evaluator::i_isSpace() { return myEvaluationMatrix->i_isSpace; }
// inline bool Evaluator::i_isAlpha() { return myEvaluationMatrix->i_isAlpha; }


// Evaluator::Evaluator(position,evalmatrix) Constructor

Evaluator::Evaluator(unsigned int s, EvaluationMatrix* m) { // Constructor...
Evaluator::Evaluator(unsigned int s, EvaluationMatrix* m)
: myEvaluationMatrix(m),
JumpPoint(0),
Condition(DOING_OK),
NextEvaluator(NULL),
StreamStartPosition(s),
CurrentPosition(0),
WildRunLength(0) { // Constructor...

myEvaluationMatrix = m; // Capture the matrix I live in.
Matrix = myEvaluationMatrix->getTokens(); // Capture the token matrix I walk in.
MatrixSize = myEvaluationMatrix->getMatrixSize(); // And get it's size.
PositionLimit = MatrixSize - 256; // Calculate the safety limit.
MatrixSize = myEvaluationMatrix->getMatrixSize(); // And get it's size.
PositionLimit = MatrixSize - 256;
}

StreamStartPosition = s; // Always record our starting point.
NextEvaluator = NULL; // Allways start off with no extensions.
CurrentPosition = 0; // Always start at the root of the matrix;
WildRunLength = 0; // No run length when new.
// Of course I may need to resolve some of the following
// wildcard characters.

Condition = DOING_OK; // Start off being ok.
}
int Evaluator::xLetter() { return (JumpPoint + WILD_LETTER); } // Match Any letter.
int Evaluator::xDigit() { return (JumpPoint + WILD_DIGIT); } // Match Any digit.
int Evaluator::xNonWhite() { return (JumpPoint + WILD_NONWHITE); } // Match Any non-whitespace.
int Evaluator::xWhiteSpace() { return (JumpPoint + WILD_WHITESPACE); } // Match Any whitespace.
int Evaluator::xAnyInline() { return (JumpPoint + WILD_INLINE); } // Match Any byte but new line.
int Evaluator::xAnything() { return (JumpPoint + WILD_ANYTHING); } // Match Any character at all.
int Evaluator::xRunGateway() { return (JumpPoint + RUN_GATEWAY); } // Match the run-loop gateway.
// void Evaluator::doFollowOrMakeBuddy()
void Evaluator::doFollowOrMakeBuddy(int xKey) {
bool shouldFollow = (FALLEN_OFF == Condition); // What should we do?
if(shouldFollow) { // This is how we follow
Condition = DOING_OK;
CurrentPosition = xKey +
Matrix[xKey].Vector;
}

else { // This is how we make a buddy
myEvaluationMatrix->
AddEvaluator(StreamStartPosition,Matrix[xKey].Vector+xKey);
}
}
void Evaluator::tryFollowingPrecisePath(unsigned short int i) {
int xPrecise = JumpPoint + i; // Match Precise Character
if(Matrix[xPrecise].Character() == i) { // If we've matched our path
doFollowOrMakeBuddy(xPrecise);
}
if(DOING_OK == Condition) WildRunLength = 0;
}
void Evaluator::tryFollowingNoCasePath(unsigned short int i) {
i = tolower(i);
int xNoCase = JumpPoint + i; // Match caps to lower (case insensitive)
if(Matrix[xNoCase].Character()==i){
doFollowOrMakeBuddy(xNoCase);
}
if(DOING_OK == Condition) WildRunLength = 0;
}
void Evaluator::tryFollowingWildAlphaPath() {
if(Matrix[xLetter()].Character()==WILD_LETTER){
doFollowOrMakeBuddy(xLetter());
}
}
void Evaluator::tryFollowingWildDigitPath() {
if(Matrix[xDigit()].Character()==WILD_DIGIT){
doFollowOrMakeBuddy(xDigit());
}
}
void Evaluator::tryFollowingWildNonWhitePath() {
if(Matrix[xNonWhite()].Character()==WILD_NONWHITE){
doFollowOrMakeBuddy(xNonWhite());
}
}
void Evaluator::tryFollowingWildWhitePath() {
if(Matrix[xWhiteSpace()].Character()==WILD_WHITESPACE){
doFollowOrMakeBuddy(xWhiteSpace());
}
}
void Evaluator::tryFollowingWildInlinePath() {
if(Matrix[xAnyInline()].Character()==WILD_INLINE){
doFollowOrMakeBuddy(xAnyInline());
}
}
void Evaluator::tryFollowingWildAnythingPath() {
if(Matrix[xAnything()].Character()==WILD_ANYTHING){
doFollowOrMakeBuddy(xAnything());
}
}
void Evaluator::doFollowerJumpTable(unsigned short int i) {
tryFollowingPrecisePath(i);
// tryFollowingUppercasePath(); 0x41 - 0x5A
// tryFollowingWildAlphaPath(); 0x61 - 0x7A
// tryFollowingWildDigitPath(); 0x30 - 0x39
// tryFollowingWildWhitePath(); 0x09 - 0x0D, 0x20
// tryFollowingWildNonWhitePath(); > 0x20
// tryFollowingWildInlinePath(); Not 0x0A, or 0x0D
switch(i) {
// These only match Precise, or WildAnything ...
// NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL, BS, TAB, LF, VT, FF, CR, SO, SI
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
case 0x08: {
break;
}
// tab
case 0x09: {
tryFollowingWildWhitePath();
tryFollowingWildInlinePath();
break;
}
// LF, VT, FF, CR, SO, SI
case 0x0A: case 0x0B: case 0x0C: case 0x0D: case 0x0E: case 0x0F:
// DLE, DC1, DC2, DC3, DC4, NAK, SYN, ETB, CAN, EM, SUB, ESC, FS, GS, RS, US
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1E: case 0x1F: {
tryFollowingWildWhitePath();
break;
}
// the final fronteer
case 0x20: {
tryFollowingWildWhitePath();
tryFollowingWildInlinePath();
break;
}
// ! " # $ % & ' ( ) * + , - . /
case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F: {
tryFollowingWildNonWhitePath();
tryFollowingWildInlinePath();
break;
}
// 0 - 9
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
case 0x38: case 0x39: {
tryFollowingWildDigitPath();
tryFollowingWildNonWhitePath();
tryFollowingWildInlinePath();
break;
}
// : ; < = > ? @
case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F:
case 0x40: {
tryFollowingWildNonWhitePath();
tryFollowingWildInlinePath();
break;
}
// A - Z
case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
case 0x48: case 0x49: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4E: case 0x4F:
case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
case 0x58: case 0x59: case 0x5A: {
tryFollowingNoCasePath(i);
tryFollowingWildAlphaPath();
tryFollowingWildNonWhitePath();
tryFollowingWildInlinePath();
break;
}
// [ \ ] ^ _ `
case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F:
case 0x60: {
tryFollowingWildNonWhitePath();
tryFollowingWildInlinePath();
break;
}
// a - z
case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6D: case 0x6E: case 0x6F:
case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
case 0x78: case 0x79: case 0x7A: {
tryFollowingWildAlphaPath();
tryFollowingWildNonWhitePath();
tryFollowingWildInlinePath();
break;
}
// { | } ~
case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F: {
tryFollowingWildNonWhitePath();
tryFollowingWildInlinePath();
}
// high ascii
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
case 0x88: case 0x89: case 0x8A: case 0x8B: case 0x8C: case 0x8D: case 0x8E: case 0x8F:
case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
case 0x98: case 0x99: case 0x9A: case 0x9B: case 0x9C: case 0x9D: case 0x9E: case 0x9F:
case 0xA0: case 0xA1: case 0xA2: case 0xA3: case 0xA4: case 0xA5: case 0xA6: case 0xA7:
case 0xA8: case 0xA9: case 0xAA: case 0xAB: case 0xAC: case 0xAD: case 0xAE: case 0xAF:
case 0xB0: case 0xB1: case 0xB2: case 0xB3: case 0xB4: case 0xB5: case 0xB6: case 0xB7:
case 0xB8: case 0xB9: case 0xBA: case 0xBB: case 0xBC: case 0xBD: case 0xBE: case 0xBF:
case 0xC0: case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7:
case 0xC8: case 0xC9: case 0xCA: case 0xCB: case 0xCC: case 0xCD: case 0xCE: case 0xCF:
case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7:
case 0xD8: case 0xD9: case 0xDA: case 0xDB: case 0xDC: case 0xDD: case 0xDE: case 0xDF:
case 0xE0: case 0xE1: case 0xE2: case 0xE3: case 0xE4: case 0xE5: case 0xE6: case 0xE7:
case 0xE8: case 0xE9: case 0xEA: case 0xEB: case 0xEC: case 0xED: case 0xEE: case 0xEF:
case 0xF0: case 0xF1: case 0xF2: case 0xF3: case 0xF4: case 0xF5: case 0xF6: case 0xF7:
case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD: case 0xFE: case 0xFF: {
tryFollowingWildNonWhitePath();
tryFollowingWildInlinePath();
break;
}
}
tryFollowingWildAnythingPath();
}
// Evaluator::EvaluateThis()

Evaluator::States Evaluator::EvaluateThis(unsigned short int i) { // Follow the this byte.

Condition = FALLEN_OFF; // Start off guessing we'll fall off.

// First upgrade will be to DOING_OK, after that we launch buddies.

Condition = FALLEN_OFF; // Start off guessing we'll fall off.

// In order to handle wildcard characters, this evaluation function must actually
// compare the character to a number of possibilities in most-specific to least-
// specific order to see if any match. In order to support overlapping rule sets,
@@ -257,33 +469,9 @@ Evaluator::States Evaluator::EvaluateThis(unsigned short int i) {
// explored. New evaluators are always added at the TOP of the list so we are always
// guaranteed not to overdrive an evaluator and end up in a recursive race condition.

// 20030216 _M Optimizations. In order to reduce the number of instructions per byte
// the parent Evaluation Matrix will now translate the byte i into boolean flags
// indicating if they are digits, white, letters, etc... and converting to lower
// case etc... This conversion is then done only once so that thereafter only a simple
// comparison need be made. This should eliminate many function calls and a collection
// of numeric comparisons.
//
// I am also moving the simple comparisons to the front of each logical section so
// that failures there can short-circuit subsequent logic to view the state of the
// matrix regardin that character. The matrix lookup is likely to be more expensive
// than a single binary comparison.

// For safety, we check our evaluation position here - If xNoCase is out of range
// then we will return OUT_OF_RANGE to indicate the problem rather than accessing
// data beyone our token matrix's limits.

/*** 20070606 _M Reduced the strength of this check from 3 comparisons to 1.
**** CurrentPosition is now an unsigned int so it cannot be negative. The limit
**** is now calculated once in the constructor as PositionLimit.

if(
CurrentPosition < 0 || // Position should never be < 0
xPrecise >= MatrixSize || // nor xPrecise over the top.
xNoCase >= MatrixSize // nor NoCase over the top.
) // If either occur we have a
return Condition = OUT_OF_RANGE; // bad matrix.
***/
// 20140121_M The previous optimization with binary flags has been replaced with
// a jump table implementation. Now, each byte only excites behaviors that are
// possible for the current byte so only those paths will be tested.

if(CurrentPosition >= PositionLimit) return Condition = OUT_OF_RANGE;

@@ -300,234 +488,17 @@ Evaluator::States Evaluator::EvaluateThis(unsigned short int i) {
// to support deep - filters which will show every rule match and this will need to
// be rewritten.

// Evaluation order, most-to-least specific:

int xPrecise = CurrentPosition + i; // Match Precise Character
int xNoCase = CurrentPosition + i_lower(); // Match Case insensitive

// Of course I may need to resolve some of the following
// wildcard characters.

int xLetter = CurrentPosition + WILD_LETTER; // Match Any letter.
int xDigit = CurrentPosition + WILD_DIGIT; // Match Any digit.
int xNonWhite = CurrentPosition + WILD_NONWHITE; // Match Any non-whitespace.
int xWhiteSpace = CurrentPosition + WILD_WHITESPACE; // Match Any whitespace.
int xAnyInline = CurrentPosition + WILD_INLINE; // Match Any byte but new line.
int xAnything = CurrentPosition + WILD_ANYTHING; // Match Any character at all.
int xRunGateway = CurrentPosition + RUN_GATEWAY; // Match the run-loop gateway.

// Try to match the precise character.

if(Matrix[xPrecise].Character() == i) { // If we've matched our path
Condition = DOING_OK; // upgrade to doing ok.
CurrentPosition = xPrecise +
Matrix[xPrecise].Vector; // Move myself along this path.
}

// Try to match the case insensitive character.

if(i_lower()!=i && Matrix[xNoCase].Character()==i_lower()){

// If we've matched our path
// with a compromized case then
if(Condition==FALLEN_OFF) { // check: if no matches yet,
Condition = DOING_OK; // upgrade to doing ok.
CurrentPosition = xNoCase +
Matrix[xNoCase].Vector; // Move myself along this path.
}
// If we more than one match then
else { // lets try to make a buddy...

// If there's no duplicate buddy like this already, then we'll create one.
// To create a buddy, add an evaluator at the top of the list (behind us) and
// set it's position as if it had been here all along and had matched the current
// character. Next time we evaluate it will be just like all the others.

myEvaluationMatrix->
AddEvaluator(StreamStartPosition,Matrix[xNoCase].Vector+xNoCase);

}
}

// Start looking at wildcards... Here's where we must limit run length.

if(Condition == DOING_OK) // If we matched above we'll
WildRunLength = 0; // reset our wild run count.
// If not then we need to keep
else { // track of our run length.

++WildRunLength; // Count up the run length.
if(WildRunLength >= MaxWildRunLength) // If we exceed the max then
return Condition = FALLEN_OFF; // we've fallen off the path
} // and we do it immediately.

// WILD_LETTER
// If that didn't do it for us...
// Try to match any letter character.

// The way this next one works (and the rest of the wildcards) is we look into
// the token matrix to see if the wildcard is part of the current path... If it
// is then we compare the incoming character to that wildcard evaluation function
// and if it is true, then we've got a match.

if(i_isAlpha() && Matrix[xLetter].Character()==WILD_LETTER){

// If we've matched our path
// with any letter then
if(Condition==FALLEN_OFF) { // check: if no matches yet,
Condition = DOING_OK; // upgrade to doing ok.
CurrentPosition = xLetter +
Matrix[xLetter].Vector; // Move myself along this path.
}

else { // Otherwise make a buddy...

// If there's no duplicate buddy like this already, then we'll create one.
// To create a buddy, add an evaluator at the top of the list (behind us) and
// set it's position as if it had been here all along and had matched the current
// character. Next time we evaluate it will be just like all the others.

myEvaluationMatrix->
AddEvaluator(StreamStartPosition,Matrix[xLetter].Vector+xLetter);

}
}

// WILD_DIGIT
// If that didn't do it for us...
// Try to match any digit character.

if(i_isDigit() && Matrix[xDigit].Character()==WILD_DIGIT){

// If we've matched our path
// with any letter then
if(Condition==FALLEN_OFF) { // check: if no matches yet,
Condition = DOING_OK; // upgrade to doing ok.
CurrentPosition = xDigit +
Matrix[xDigit].Vector; // Move myself along this path.
}

else { // Otherwise make a buddy...

// If there's no duplicate buddy like this already, then we'll create one.
// To create a buddy, add an evaluator at the top of the list (behind us) and
// set it's position as if it had been here all along and had matched the current
// character. Next time we evaluate it will be just like all the others.

myEvaluationMatrix->
AddEvaluator(StreamStartPosition,Matrix[xDigit].Vector+xDigit);

}
}

// WILD_NONWHITE
// If that didn't do it for us...
// Try to match any non-whitespace character.

if(!i_isSpace() && Matrix[xNonWhite].Character()==WILD_NONWHITE){

// If we've matched our path
// with any letter then
if(Condition==FALLEN_OFF) { // check: if no matches yet,
Condition = DOING_OK; // upgrade to doing ok.
CurrentPosition = xNonWhite +
Matrix[xNonWhite].Vector; // Move myself along this path.
}

else { // Otherwise make a buddy...

// If there's no duplicate buddy like this already, then we'll create one.
// To create a buddy, add an evaluator at the top of the list (behind us) and
// set it's position as if it had been here all along and had matched the current
// character. Next time we evaluate it will be just like all the others.

myEvaluationMatrix->
AddEvaluator(StreamStartPosition,Matrix[xNonWhite].Vector+xNonWhite);

}
}

// WILD_WHITESPACE
// If that didn't do it for us...
// Try to match any whitespace character.

if(i_isSpace() && Matrix[xWhiteSpace].Character()==WILD_WHITESPACE){

// If we've matched our path
// with any whitespace then
if(Condition==FALLEN_OFF) { // check: if no matches yet,
Condition = DOING_OK; // upgrade to doing ok.
CurrentPosition = xWhiteSpace +
Matrix[xWhiteSpace].Vector; // Move myself along this path.
}

else { // Otherwise make a buddy...

// If there's no duplicate buddy like this already, then we'll create one.
// To create a buddy, add an evaluator at the top of the list (behind us) and
// set it's position as if it had been here all along and had matched the current
// character. Next time we evaluate it will be just like all the others.

myEvaluationMatrix->
AddEvaluator(StreamStartPosition,Matrix[xWhiteSpace].Vector+xWhiteSpace);

}
}

// WILD_INLINE
// If that didn't do it for us...
// Try to match any character EXCEPT a new line.

if(i != '\n' && Matrix[xAnyInline].Character()==WILD_INLINE){

// If we've matched our path
// with any byte but \n then
if(Condition==FALLEN_OFF) { // check: if no matches yet,
Condition = DOING_OK; // upgrade to doing ok.
CurrentPosition = xAnyInline +
Matrix[xAnyInline].Vector; // Move myself along this path.
}

else { // Otherwise make a buddy...

// If there's no duplicate buddy like this already, then we'll create one.
// To create a buddy, add an evaluator at the top of the list (behind us) and
// set it's position as if it had been here all along and had matched the current
// character. Next time we evaluate it will be just like all the others.

myEvaluationMatrix->
AddEvaluator(StreamStartPosition,Matrix[xAnyInline].Vector+xAnyInline);

}
}

// WILD_ANYTHING
// If that didn't do it for us...
// Try to match any character.

if(Matrix[xAnything].Character()==WILD_ANYTHING){

// If we've matched our path
// with any letter then
if(Condition==FALLEN_OFF) { // check: if no matches yet,
Condition = DOING_OK; // upgrade to doing ok.
CurrentPosition = xAnything +
Matrix[xAnything].Vector; // Move myself along this path.
}

else { // Otherwise make a buddy...

// If there's no duplicate buddy like this already, then we'll create one.
// To create a buddy, add an evaluator at the top of the list (behind us) and
// set it's position as if it had been here all along and had matched the current
// character. Next time we evaluate it will be just like all the others.

myEvaluationMatrix->
AddEvaluator(StreamStartPosition,Matrix[xAnything].Vector+xAnything);

}
}
// Evaluation order, most-to-least specific with what is possible for that byte.

JumpPoint = CurrentPosition;
doFollowerJumpTable(i); // Excite followers based on this byte.
{ // Precise matches reset the wild run counter.
++WildRunLength; // Count up the run length.
if(WildRunLength >= MaxWildRunLength) // If we exceed the max then
return Condition = FALLEN_OFF; // we've fallen off the path
} // and we do it immediately.
// 20021112 _M
// Beginning with version 2 of Message Sniffer we've implemented a new construct
// for run-loops that prevents any interference between rules where run-loops might
@@ -550,9 +521,9 @@ Evaluator::States Evaluator::EvaluateThis(unsigned short int i) {
// could be behind the gateway - so we launch the buddy behind us and he will be able
// to match anything in this pass that we missed when looking for a non-run match.

if(Matrix[xRunGateway].Character() == RUN_GATEWAY)
if(Matrix[xRunGateway()].Character() == RUN_GATEWAY)
myEvaluationMatrix->
InsEvaluator(StreamStartPosition,Matrix[xRunGateway].Vector+xRunGateway);
InsEvaluator(StreamStartPosition,Matrix[xRunGateway()].Vector+xRunGateway());

// At this point, we've tried all of our rules, and created any buddies we needed.
// If we got a match, we terminated long ago. If we didn't, then we either stayed
@@ -721,11 +692,12 @@ int EvaluationMatrix::EvaluateThis(unsigned short int i) {
// Next do some basic conversions and evaluations so they don't need to be done
// again within the evaluators. From now on the evaluators will look here for basic
// conversions and boolean check values rather than performing the checks themselves.

i_lower = tolower(i); // Convert i to lower case.
i_isDigit = isdigit(i); // Check for a digit.
i_isSpace = isspace(i); // Check for whitespace.
i_isAlpha = isalpha(i); // Check for letters.
// 20140119 _M deprecated by jump table in evaluator
// i_lower = tolower(i); // Convert i to lower case.
// i_isDigit = isdigit(i); // Check for a digit.
// i_isSpace = isspace(i); // Check for whitespace.
// i_isAlpha = isalpha(i); // Check for letters.

// Next, loop through the list and pass the incoming character to
// each evaluator. Drop those that fall off, and record those that terminate. The

+ 32
- 9
snf_engine.hpp 查看文件

@@ -260,11 +260,33 @@ class Evaluator { // Evaluator class for following threads through the matrix.
unsigned int PositionLimit; // Largest CurrentPosition.

// 20030216 _M Optimization conversions

inline int i_lower(); // { return myEvaluationMatrix->i_lower; }
inline bool i_isDigit(); // { return myEvaluationMatrix->i_isDigit; }
inline bool i_isSpace(); // { return myEvaluationMatrix->i_isSpace; }
inline bool i_isAlpha(); // { return myEvaluationMatrix->i_isAphpa; }
// 20140119 _M Deprecated by jump table in evaluator
// inline int i_lower(); // { return myEvaluationMatrix->i_lower; }
// inline bool i_isDigit(); // { return myEvaluationMatrix->i_isDigit; }
// inline bool i_isSpace(); // { return myEvaluationMatrix->i_isSpace; }
// inline bool i_isAlpha(); // { return myEvaluationMatrix->i_isAphpa; }
unsigned int JumpPoint;
int xLetter(); // Match Any letter.
int xDigit(); // Match Any digit.
int xNonWhite(); // Match Any non-whitespace.
int xWhiteSpace(); // Match Any whitespace.
int xAnyInline(); // Match Any byte but new line.
int xAnything(); // Match Any character at all.
int xRunGateway(); // Match the run-loop gateway.
void doFollowOrMakeBuddy(int keyVector); // Follow and divide algorithm.
void tryFollowingPrecisePath(unsigned short int i);
void tryFollowingNoCasePath(unsigned short int i);
void tryFollowingWildAlphaPath();
void tryFollowingWildDigitPath();
void tryFollowingWildNonWhitePath();
void tryFollowingWildWhitePath();
void tryFollowingWildInlinePath();
void tryFollowingWildAnythingPath();
void doFollowerJumpTable(unsigned short int i);

public:

@@ -413,10 +435,11 @@ class EvaluationMatrix {

// 20030216 _M High Level Conversion Optimizers...

int i_lower; // Lower case version of byte under test.
bool i_isDigit; // true if i is a digit.
bool i_isSpace; // true if i is whitespace.
bool i_isAlpha; // true if i is alpha.
// 20140119 _M Deprecated by jump table in evaluator
// int i_lower; // Lower case version of byte under test.
// bool i_isDigit; // true if i is a digit.
// bool i_isSpace; // true if i is whitespace.
// bool i_isAlpha; // true if i is alpha.

// AddEvaluator() is made public because the Evaluator object must have access
// to it in order to handle the creation of buddies as it evaluates it's rules.

Loading…
取消
儲存