Následuje ukázka implementace lexikální analýzy první úrovně (zde rozpoznávání příkazů) podmnožiny příkazů Příkazového řádku Windows.
package wintrainer;
/**
*
* @author sarka
*/
// trida pro lexikalni analyzu nazvu prikazu, prvni uroven (pouze nazvy prikazu, bez parametru)
public class TLex {
public int typsymbolu; // typ symbolu, definovano v TTypSymbolu
char[] rad; // nacteny radek
int pos; // pozice na radku
int delka; // delka radku
int stav, stavold; // stav konecneho automatu
String params = new String(); // parametry zadaneho prikazu k dalsimu zpracovani
public TLex () { // konstruktor, vpodstate neni potreba, viz getSym()
pos = 0;
delka = 0;
}
public int getSym (String str) {
str = str.trim() + ' '; // ostranime okolni prazdne znaky, na konec pridame mezeru
rad = str.toLowerCase().toCharArray();// nebude case-sensitive
pos = 0;
delka = str.length();
stav = 1; // pozor, pocatecni stav je 1, ne 0!
if (pos == delka) return TTypSymbolu.SInvalid;
while (pos < delka && stav > 0 && stav < TTypSymbolu.SFirstSymbolType) {
switch (stav) {
case 1: switch (rad[pos]) {
case 'a': stav = 2; break;
case 'c': stav = 11; break;
case 'd': stav = 22; break;
case 'e': stav = 27; break;
case 'f': stav = 32; break;
case 'h': stav = 42; break;
case 'i': stav = 45; break;
case 'm': stav = 52; break;
case 'n': stav = 59; break;
case 'p': stav = 71; break;
case 'r': stav = 80; break;
case 's': stav = 88; break;
case 't': stav = 101; break;
case 'v': stav = 121; break;
case 'w': stav = 123; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
}
break;
case 2: switch (rad[pos]) {
case 'r': stav = 3; break;
case 't': stav = 4; break; // ************* SAt, nebo pripadne SAttrib
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 3: if (rad[pos] == 'p') { stav = TTypSymbolu.SArp; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 4: if (rad[pos] == 't') { stav = 5; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 5: if (rad[pos] == 'r') { stav = 6; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 6: if (rad[pos] == 'i') { stav = 7; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 7: if (rad[pos] == 'b') { stav = TTypSymbolu.SAttrib; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 11: switch (rad[pos]) {
case ':': stav = TTypSymbolu.SDiskC; break;
case 'a': stav = 12; break;
case 'd': stav = TTypSymbolu.SCd; break;
case 'h': stav = 15; break;
case 'l': stav = 18; break;
case 'o': stav = 19; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 12: if (rad[pos] == 'c') { stav = 13; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 13: if (rad[pos] == 'l') { stav = 14; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 14: if (rad[pos] == 's') { stav = TTypSymbolu.SCacls; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 15: if (rad[pos] == 'd') { stav = 16; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 16: if (rad[pos] == 'i') { stav = 17; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 17: if (rad[pos] == 'r') { stav = TTypSymbolu.SChdir; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 18: if (rad[pos] == 's') { stav = TTypSymbolu.SCls; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 19: switch (rad[pos]) {
case 'm': stav = 20; break;
case 'p': stav = 21; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 20: if (rad[pos] == 'p') { stav = TTypSymbolu.SComp; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 21: if (rad[pos] == 'y') { stav = TTypSymbolu.SCopy; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 22: switch (rad[pos]) {
case ':': stav = TTypSymbolu.SDiskD; break;
case 'a': stav = 23; break;
case 'e': stav = 25; break;
case 'i': stav = 26; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 23: if (rad[pos] == 't') { stav = 24; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 24: if (rad[pos] == 'e') { stav = TTypSymbolu.SDate; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 25: if (rad[pos] == 'l') { stav = TTypSymbolu.SDel; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 26: if (rad[pos] == 'r') { stav = TTypSymbolu.SDir; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 27: switch (rad[pos]) {
case 'd': stav = 28; break;
case 'c': stav = 30; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 28: if (rad[pos] == 'i') { stav = 29; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 29: if (rad[pos] == 't') { stav = TTypSymbolu.SEdit; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 30: if (rad[pos] == 'h') { stav = 31; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 31: if (rad[pos] == 'o') { stav = TTypSymbolu.SEdit; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 32: switch (rad[pos]) {
case 'c': stav = TTypSymbolu.SFc; break;
case 'i': stav = 33; break;
case 's': stav = 38; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 33: if (rad[pos] == 'n') { stav = 34; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 34: if (rad[pos] == 'd') { stav = 35; } // ******************** SFind nebo SFindstr
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 35: if (rad[pos] == 's') { stav = 36; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 36: if (rad[pos] == 't') { stav = 37; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 37: if (rad[pos] == 'r') { stav = TTypSymbolu.SFindstr; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 38: if (rad[pos] == 'u') { stav = 39; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 39: if (rad[pos] == 't') { stav = 40; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 40: if (rad[pos] == 'i') { stav = 41; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 41: if (rad[pos] == 'l') { stav = TTypSymbolu.SFsutil; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 42: if (rad[pos] == 'e') { stav = 43; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 43: if (rad[pos] == 'l') { stav = 44; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 44: if (rad[pos] == 'p') { stav = TTypSymbolu.SHelp; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 45: if (rad[pos] == 'p') { stav = 46; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 46: if (rad[pos] == 'c') { stav = 47; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 47: if (rad[pos] == 'o') { stav = 48; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 48: if (rad[pos] == 'n') { stav = 49; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 49: if (rad[pos] == 'f') { stav = 50; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 50: if (rad[pos] == 'i') { stav = 51; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 51: if (rad[pos] == 'g') { stav = TTypSymbolu.SIpconfig; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 52: switch (rad[pos]) {
case 'd': stav = TTypSymbolu.SMd; break;
case 'k': stav = 53; break;
case 'o': stav = 56; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 53: if (rad[pos] == 'd') { stav = 54; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 54: if (rad[pos] == 'i') { stav = 55; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 55: if (rad[pos] == 'r') { stav = TTypSymbolu.SMkdir; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 56: switch (rad[pos]) {
case 'r': stav = 57; break;
case 'v': stav = 58; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 57: if (rad[pos] == 'e') { stav = TTypSymbolu.SMore; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 58: if (rad[pos] == 'e') { stav = TTypSymbolu.SMove; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 59: switch (rad[pos]) {
case 'e': stav = 60; break;
case 's': stav = 65; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 60: if (rad[pos] == 't') { stav = 61; } // ************** SNet nebo SNetsh nebo SNetstat
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 61: if (rad[pos] == 's') { stav = 62; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 62: switch (rad[pos]) {
case 'h': stav = TTypSymbolu.SNetsh; break;
case 't': stav = 63; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 63: if (rad[pos] == 'a') { stav = 64; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 64: if (rad[pos] == 't') { stav = TTypSymbolu.SNetstat; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 65: if (rad[pos] == 'l') { stav = 66; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 66: if (rad[pos] == 'o') { stav = 67; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 67: if (rad[pos] == 'o') { stav = 68; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 68: if (rad[pos] == 'k') { stav = 69; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 69: if (rad[pos] == 'u') { stav = 70; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 70: if (rad[pos] == 'p') { stav = TTypSymbolu.SNslookup; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 71: switch (rad[pos]) {
case 'a': stav = 72; break;
case 'i': stav = 78; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 72: if (rad[pos] == 't') { stav = 73; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 73: if (rad[pos] == 'h') { stav = 74; } // ************** SPath nebo SPathping
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 74: if (rad[pos] == 'p') { stav = 75; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 75: if (rad[pos] == 'i') { stav = 76; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 76: if (rad[pos] == 'n') { stav = 77; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 77: if (rad[pos] == 'g') { stav = TTypSymbolu.SPathping; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 78: if (rad[pos] == 'n') { stav = 79; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 79: if (rad[pos] == 'g') { stav = TTypSymbolu.SPing; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 80: switch (rad[pos]) {
case 'd': stav = TTypSymbolu.SRd; break;
case 'e': stav = 81; break;
case 'm': stav = 82; break;
case 'o': stav = 85; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 81: switch (rad[pos]) {
case 'g': stav = TTypSymbolu.SReg; break;
case 'n': stav = TTypSymbolu.SRen; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 82: if (rad[pos] == 'd') { stav = 83; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 83: if (rad[pos] == 'i') { stav = 84; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 84: if (rad[pos] == 'r') { stav = TTypSymbolu.SRmdir; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 85: if (rad[pos] == 'u') { stav = 86; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 86: if (rad[pos] == 't') { stav = 87; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 87: if (rad[pos] == 'e') { stav = TTypSymbolu.SRoute; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 88: switch (rad[pos]) {
case 'c': stav = 90; break; // ********** SSc nebo SSchtasks
case 'e': stav = 89; break;
case 'o': stav = 96; break;
case 't': stav = 98; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 89: if (rad[pos] == 't') { stav = TTypSymbolu.SSet; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 90: if (rad[pos] == 'h') { stav = 91; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 91: if (rad[pos] == 't') { stav = 92; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 92: if (rad[pos] == 'a') { stav = 93; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 93: if (rad[pos] == 's') { stav = 94; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 94: if (rad[pos] == 'k') { stav = 95; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 95: if (rad[pos] == 's') { stav = TTypSymbolu.SSchtasks; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 96: if (rad[pos] == 'r') { stav = 97; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 97: if (rad[pos] == 't') { stav = TTypSymbolu.SSort; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 98: if (rad[pos] == 'a') { stav = 99; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 99: if (rad[pos] == 'r') { stav = 100; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 100: if (rad[pos] == 't') { stav = TTypSymbolu.SStart; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 101: switch (rad[pos]) {
case 'a': stav = 102; break;
case 'i': stav = 111; break;
case 'r': stav = 113; break;
case 'y': stav = 119; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 102: if (rad[pos] == 's') { stav = 103; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 103: if (rad[pos] == 'k') { stav = 104; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 104: switch (rad[pos]) {
case 'k': stav = 105; break;
case 'l': stav = 108; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 105: if (rad[pos] == 'i') { stav = 106; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 106: if (rad[pos] == 'l') { stav = 107; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 107: if (rad[pos] == 'l') { stav = TTypSymbolu.STaskkill; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 108: if (rad[pos] == 'i') { stav = 109; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 109: if (rad[pos] == 's') { stav = 110; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 110: if (rad[pos] == 't') { stav = TTypSymbolu.STasklist; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 111: if (rad[pos] == 'm') { stav = 112; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 112: if (rad[pos] == 'e') { stav = TTypSymbolu.STime; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 113: switch (rad[pos]) {
case 'a': stav = 114; break;
case 'e': stav = 118; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 114: if (rad[pos] == 'c') { stav = 115; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 115: if (rad[pos] == 'e') { stav = 116; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 116: if (rad[pos] == 'r') { stav = 117; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 117: if (rad[pos] == 't') { stav = TTypSymbolu.STracert; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 118: if (rad[pos] == 'e') { stav = TTypSymbolu.STree; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 119: if (rad[pos] == 'p') { stav = 120; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 120: if (rad[pos] == 'e') { stav = TTypSymbolu.SType; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 121: if (rad[pos] == 'e') { stav = 122; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 122: if (rad[pos] == 'r') { stav = TTypSymbolu.SVer; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 123: switch (rad[pos]) {
case 'i': stav = 124; break;
case 'm': stav = 128; break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} break;
case 124: if (rad[pos] == 'n') { stav = 125; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 125: if (rad[pos] == 'v') { stav = 126; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 126: if (rad[pos] == 'e') { stav = 127; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 127: if (rad[pos] == 'r') { stav = TTypSymbolu.SWinver; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 128: if (rad[pos] == 'm') { stav = 129; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 129: if (rad[pos] == 'i') { stav = 130; } else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
case 130: if (rad[pos] == 'c') { stav = TTypSymbolu.SWmic; }
else { stavold = stav; stav = TTypSymbolu.SInvalid; } break;
default: { stavold = stav; stav = TTypSymbolu.SInvalid; }
} // switch
pos++;
// if (stav == 0 || stav >= TTypSymbolu.SFirstSymbolType) break;
} // while
// vyresime "konflikty", tj. pokud jeden nazev prikazu je soucasti jineho nazvu
if (stav == TTypSymbolu.SInvalid) {
pos--;
switch (stavold) {
case 4: stav = TTypSymbolu.SAt; break;
case 35: stav = TTypSymbolu.SFind; break;
case 61: stav = TTypSymbolu.SNet; break;
case 74: stav = TTypSymbolu.SPath; break;
case 90: stav = TTypSymbolu.SSc; break;
}
}
// za cislem by nemelo hned nasledovat pismeno, byl by to chybny symbol
if (stav < TTypSymbolu.SFirstSymbolType ||
Character.isDigit(rad[pos]) || Character.isLetter(rad[pos]))
{ stav = TTypSymbolu.SInvalid; }
else if (stav == TTypSymbolu.SCd) params = String.copyValueOf(rad,pos,delka-pos);
else { params = String.copyValueOf(rad, pos+1, delka-pos-1); }
typsymbolu = stav;
return stav;
} // getSym
} // class