Překladače - lexikální analýza první úrovně

 

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