⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 makescan.p

📁 PL/0源码
💻 P
字号:
(*====================================    MAKESCAN    reads tables file produced by scangen and writes C variable definitions    on standard output for appropriate tables to be linked into the scanner======================================*)program makescan (tables, output);#include "scanner.h"const    HASH_TABLE_SIZE     = 3001;     {3001 is prime}    MAX_CHAR_CODE       = 127;    MAX_CHAR_CLASS      = 45;    MAX_SCANNER_STATE   = 60;    MAX_RESERVE_WORD    = 50;    ERROR           = 0;    MOVE_APPEND     = 1;    MOVE_NO_APPEND  = 2;    HALT_APPEND     = 3;    HALT_NO_APPEND  = 4;    HALT_REUSE      = 5;    type    HashTableIndex = 1..HASH_TABLE_SIZE;    CharClass = 0..MAX_CHAR_CLASS;    ScannerState = 0..MAX_SCANNER_STATE;    ScannerAction = ERROR..HALT_REUSE;    ReserveWord = 1..MAX_RESERVE_WORD;    StateVector = record        case action : ScannerAction of            MOVE_APPEND,            MOVE_NO_APPEND :                (nextState : ScannerState);            HALT_APPEND,            HALT_NO_APPEND,            HALT_REUSE    :                (major : MajorTokenNum;                 minor : MinorTokenNum)        end;    StateInfoRec = record        case terminal : Boolean of            true :                (defaultMajor : MajorTokenNum;                 defaultMinor : MinorTokenNum)    end;    ReserveArrayRec = record        major : MajorTokenNum;        minor : MinorTokenNum;        ssLoc : StringSpaceIndex;    end;var    tables : text;    scannerStringSpace : array[1..MAX_STRING_SPACE] of char;    nextFreeStringSpace : StringSpaceIndex;    hashTable : array[HashTableIndex] of StringSpaceIndex;    reserveWordArray : array[1..MAX_RESERVE_WORD] of ReserveArrayRec;    charClassArray : array[0..MAX_CHAR_CODE] of CharClass;    stateMatrix : array[1..MAX_SCANNER_STATE, 1..MAX_CHAR_CLASS] of StateVector;    stateInfoArray : array[1..MAX_SCANNER_STATE] of StateInfoRec;        {keeps track of which states are terminal, and for what}    numReserveWords : ReserveWord;    endOfFile : MajorTokenNum;    scannerNumTerms : MajorTokenNum;    startState : ScannerState;    maxReserveLocation : StringSpaceIndex;    idMajorNum : MajorTokenNum;    idMinorNum : MinorTokenNum;(********    Inserts a character into the next available    slot in StringSpace.  Checks against overflow.    Converts all lower-case characters to upper case, on the assumption    that case is insignificant. ********)procedure InsertStringSpace (ch : char);begin    if nextFreeStringSpace = MAX_STRING_SPACE then begin            {we are about to overflow}        message ('Out of room in scanner string storage area.');        halt;    end;    if ch in ['a'..'z'] then        ch := chr (ord (ch) - (ord ('a') - ord ('A')));    scannerStringSpace[nextFreeStringSpace] := ch;    nextFreeStringSpace := nextFreeStringSpace + 1end; {InsertStringSpace}(********    produce C generate_code initialized globals for all static variables ********)procedure OutputTables;var    i, j : integer;begin    writeln('#include "scantab.h"');    write ('char st_string_space[', MAX_STRING_SPACE:1, '] = "');    for i := 1 to nextFreeStringSpace - 1 do        if scannerStringSpace[i] = chr (NULL) then            write ('\0')        else            write (scannerStringSpace[i]);    writeln ('";');    writeln ('short st_used_strings = ', nextFreeStringSpace:1, ';');    writeln ('reserve_array_t st_reserved_words[] = {');    for i := 1 to numReserveWords-1 do begin        with reserveWordArray[i] do            writeln ('  {', major:1, ', ', minor:1,                ', ', (ssLoc - 1):1, '},');    end;    with reserveWordArray[numReserveWords] do        writeln ('  {', major:1, ', ', minor:1,            ', ', (ssLoc - 1):1, '}};');    write ('char st_char_class[] = {');    for i := 0 to MAX_CHAR_CODE-1 do begin        if i mod 5 = 0 then begin            writeln;            write (tab);        end;        write ((charClassArray[i]-1):1, ', '); (* !!GCH *)    end;    writeln (charClassArray[MAX_CHAR_CODE]:1, '};'); (* !!GCH *)    writeln ('state_vector_t st_state_matrix[',        MAX_SCANNER_STATE:1, '][', MAX_CHAR_CLASS:1, '] = {');    for i := 1 to MAX_SCANNER_STATE do begin	writeln('  { ');        for j := 1 to MAX_CHAR_CLASS do begin            with stateMatrix[i,j] do begin                write ('    {', action:1, ',');                case action of                    ERROR : write ('0,0,0}');                    MOVE_APPEND,                    MOVE_NO_APPEND : write ((nextState-1):1, ',0,0}'); (* !!GCH *)                    HALT_APPEND,                    HALT_NO_APPEND,                    HALT_REUSE    : write ('0,', major:1, ',', minor:1,'}');                end; (*case*)                if (j <> MAX_CHAR_CLASS) then                    writeln (',');	    end; (*with*)	end; (*for j*)	if (i = MAX_SCANNER_STATE) then	    writeln('  } ')	else	    writeln('  }, ');    end; (*for i*)    writeln('};');    writeln ('state_info_t st_state_info [] = {');    for i := 1 to MAX_SCANNER_STATE do        with stateInfoArray[i] do begin            if terminal then                write ('    { true, ', defaultMajor:1, ', ', defaultMinor:1,		       ' }')            else		write ('    { false, 0, 0 }');            if i = MAX_SCANNER_STATE then                writeln ('};')            else                writeln (',');        end; (*with*)    writeln ('char st_num_reserved_words = ', numReserveWords:1, ';');    writeln ('char st_end_of_file = ', endOfFile:1, ';');    writeln ('char st_num_terminals = ', scannerNumTerms:1, ';');    writeln ('char st_start_state = ', (startState-1):1, ';'); (* GCH!! *)    writeln ('short st_max_reserve_location = ', maxReserveLocation:1, ';');    writeln ('char st_id_major_num = ', idMajorNum:1, ';');    writeln ('char st_id_minor_num = ', idMinorNum:1, ';');end; (*OutputTables*)(********    Establishes initial values for all static variables in this module.    tables contains output from the DFA generator and is passed here    from main module. ********)procedure Initialize;var    i : HashTableIndex;    j : 0..MAX_CHAR_CODE;    numStates : ScannerState;    numClasses : CharClass;    numLists : integer;    (********        Inserts all reserved words into hashTable, reserveWordArray,        and scannerStringSpace.     ********)    procedure HashReserveWords (numReserveWords : ReserveWord);    var        ch : char;        i : ReserveWord;        start : StringSpaceIndex;    begin        for i := 1 to numReserveWords do begin            start := nextFreeStringSpace;            read (tables, ch);            repeat                InsertStringSpace (ch);                read (tables, ch);            until ch = BLANK;            InsertStringSpace (chr (NULL));            with reserveWordArray[i] do begin                read (tables, major, minor);                if (major >= endOfFile) then                    endOfFile := major + 1;                ssLoc := start;		(*start will be changed iff this reserve word is a duplicate*)                if start <> ssLoc then begin                    message (scannerStringSpace);                    message ('***** INTERNAL ERROR: ',                        'multiple identical keywords.');                    halt;                end;            end; (*with*)            readln (tables);        end    end; (*HashReserveWords*)    (********        Initializes stateMatrix and stateInfoArray.     ********)    procedure CreateStateMatrix (numStates : ScannerState;                                   numClasses : CharClass);    var        i : ScannerState;        j : CharClass;        x : integer;    (*dummy variable for read-in*)    begin        for i := 1 to numStates do begin            stateInfoArray[i].terminal := false;    (*at least temporarily*)            for j := 1 to numClasses do                with stateMatrix[i,j] do begin                    read (tables, x);                    action := x;                    if action <> ERROR then                        if action in [MOVE_APPEND, MOVE_NO_APPEND] then begin                            read (tables, x);                            nextState := x                        end                        else begin                            read (tables, x);                            major := x;                            if (major >= endOfFile) then                                (*we want endOfFile one greater than top token*)                                endOfFile := major + 1;                            read (tables, x);                            minor := x;                            if action = HALT_REUSE then                                with stateInfoArray[i] do begin                                        (*load terminal values*)                                    terminal := true;                                    defaultMajor := major;                                    defaultMinor := minor                                end (*inner with*)                        end                end (*with*)        end (*for*)    end; (*CreateStateMatrix*)begin (*Initialize*)    nextFreeStringSpace := 1;    for i := 1 to HASH_TABLE_SIZE do        hashTable[i] := NULL;    reset (tables);    read (tables, numStates, startState, numClasses, numReserveWords, numLists);    if numLists <> 1 then begin        message (' ');        message ('***** INTERNAL ERROR: Scanner does not accept multiple');        message ('                      classes of reserve words.');        halt    end;    readln (tables);    for j := 0 to MAX_CHAR_CODE do        read (tables, charClassArray[j]);    readln (tables);    read (tables, idMajorNum, idMinorNum);    readln (tables);    endOfFile := 0;     (*Increased by HashReserveWords and CreateStateMatrix*)    HashReserveWords (numReserveWords);    maxReserveLocation := nextFreeStringSpace - 1;    CreateStateMatrix (numStates, numClasses);    scannerNumTerms := endOfFile;   (*return so can check with parser*)end; (*Initialize*)begin (*main*)    Initialize;    OutputTables;end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -