'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm,
'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x, 'y, 'z => {
i: CARDINAL ← 0;
DO
buffer[i] ← char;
IF (tI←tI+1) = tMax THEN FillBuffer[];
char ← tB[tI];
SELECT char
FROM
IN ['a..'z],
IN ['A..'Z],
IN ['0..'9] =>
IF (i ← i+1) >= iMax THEN ExpandBuffer[];
ENDCASE => EXIT;
ENDLOOP;
desc.length ← i+1;
class ← tokenID; value.r ← HashOps.EnterString[desc];
GO TO GotNext};
'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H, 'I, 'J, 'K, 'L, 'M,
'N, 'O, 'P, 'Q, 'R, 'S, 'T, 'U, 'V, 'W, 'X, 'Y, 'Z => {
i: CARDINAL ← 0;
uId: BOOL ← TRUE;
first, last: NAT ← char.ORD;
DO
buffer[i] ← char;
IF (tI←tI+1) = tMax THEN FillBuffer[];
char ← tB[tI];
SELECT char
FROM
IN ['A..'Z] => {
last ← char.ORD; IF (i ← i+1) >= iMax THEN ExpandBuffer[]};
IN ['a..'z],
IN ['0..'9] => {
uId ← FALSE; IF (i ← i+1) >= iMax THEN ExpandBuffer[]};
ENDCASE => EXIT;
ENDLOOP;
i ← i+1;
IF uId
THEN {
h: HashIndex ← ((first*128-first) + last) MOD HashIndex.LAST + 1;
j, s1, s2: CARDINAL;
WHILE (j ← hashTab[h].symbol) # 0
DO
IF vocabIndex[j]-(s2←vocabIndex[j-1]) = i
THEN
FOR s1
IN [0 .. i)
DO
IF buffer[s1] # vocab.text[s2] THEN EXIT;
s2 ← s2+1;
REPEAT
FINISHED => {class ← j; GO TO GotNext};
ENDLOOP;
IF (h ← hashTab[h].link) = 0 THEN EXIT;
ENDLOOP};
desc.length ← i;
class ← tokenID; value.r ← HashOps.EnterString[desc];
GO TO GotNext};
',, ';, ':, '←, '#, '~, '+, '*, '/, '^, '@, '!,
'=, '.,
'(, '), '[, '], '{, '} => {
class ← scanTab[char]; GO TO GetNext};
'" => {
i: CARDINAL ← 0;
valid: BOOL;
advance: BOOL ← TRUE;
DO
IF advance
THEN {
IF (tI←tI+1) = tMax THEN {IF tEnded THEN GO TO EOFEnd; FillBuffer[]};
char ← tB[tI]};
SELECT char
FROM
'" => {
IF (tI←tI+1) = tMax THEN FillBuffer[];
char ← tB[tI];
IF char # '" THEN GO TO QuoteEnd};
ENDCASE;
IF i >= iMax
THEN ExpandBuffer[
! BufferOverflow => {ScanError[string, index]; i ← 0; CONTINUE}];
[buffer[i], valid, advance] ← Escape[]; i ← i+1;
IF ~valid THEN ScanError[$escape, tOrigin + tI];
REPEAT
QuoteEnd => NULL;
EOFEnd => {ScanError[$string, index]; FillBuffer[]; char ← tB[tI]};
ENDLOOP;
desc.length ← i;
value.r ← HashOps.EnterString[desc];
class ← tokenSTR; GO TO GotNext};
'- => {
NextChar[];
IF char # '-
THEN {
class ← scanTab['-];
IF class = 0 THEN ScanError[char, index-1];
GO TO GotNext};
char ← Ascii.NUL;
DO
pChar: CHAR ~ char;
IF (tI←tI+1) = tMax THEN {IF tEnded THEN GO TO EndFile; FillBuffer[]};
char ← tB[tI];
SELECT char
FROM
'- => IF pChar = '- THEN EXIT;
Ascii.CR => EXIT;
ENDCASE;
ENDLOOP;
NextChar[]};
'< => {
NextChar[];
SELECT char
FROM
'< => {
state: {plain, leftBrocket, rightBrocket} ← $plain;
nest: CARDINAL ← 1;
DO
IF (tI←tI+1) = tMax
THEN {
IF tEnded THEN GO TO EndFile; FillBuffer[]};
char ← tB[tI];
SELECT char
FROM
'> =>
SELECT state
FROM
$plain, $leftBrocket => state ← $rightBrocket;
$rightBrocket => {
state ← $plain; nest ← nest - 1; IF nest = 0 THEN EXIT};
ENDCASE;
'< =>
SELECT state
FROM
$plain, $rightBrocket => state ← $leftBrocket;
$leftBrocket => {state ← $plain; nest ← nest + 1};
ENDCASE;
ENDCASE => state ← $plain;
ENDLOOP;
NextChar[]};
ENDCASE => ScanError[$char, index]};
ENDCASE => {
class ← scanTab[char];
IF class # 0 THEN GO TO GetNext;
NextChar[];
ScanError[$char, index]};