SELECT NextChar[ !
IO.EndOfStream =>
GO
TO EOFReturn]
FROM
IN [
IO.
NUL ..
IO.
SP] => {
white space
charsSkipped ¬ charsSkipped + 1;
};
'( => {
left-paren or comment
prev: CHAR ¬ IO.CR;
depth: INT ¬ 1;
tokenKind ¬ $tokenSINGLE;
IF NextChar[! IO.EndOfStream => GO TO Return] # '* THEN GO TO PutbackReturn;
tokenKind ¬ $tokenCOMMENT;
IF flushComments
THEN {
charsSkipped ¬ charsSkipped + 2; -- for the leading two dashes
DO
SELECT NextCharSkip[ !
IO.EndOfStream =>
GO
TO eof]
FROM
') => IF prev = '* THEN {IF (depth ¬ depth-1) = 0 THEN EXIT};
'* =>
IF prev = '(
THEN {depth ¬ depth+1; char ¬ 'x};
"Sys. Prog. with M3" gives no consideration to string literals within comments.
ENDCASE;
prev ¬ char;
ENDLOOP;
EXITS eof => {};
}
ELSE
DO
SELECT NextChar[ !
IO.EndOfStream =>
GO
TO Return]
FROM
') =>
IF prev = '*
THEN {
IF (depth ¬ depth-1) = 0
THEN
GO
TO Return};
Must include the trailing *) in the comment
'* => IF prev = '( THEN {depth ¬ depth+1; char ¬ 'x};
ENDCASE;
prev ¬ char;
ENDLOOP;
};
'< => {
less-than, less-or-equal, subtype, or pragma
prev: CHAR ¬ IO.CR;
depth: INT ¬ 0;
tokenKind ¬ $tokenSINGLE;
SELECT NextChar[!
IO.EndOfStream =>
GO
TO Return]
FROM
'* => depth ¬ 1;
': => GO TO DoubleReturn;
'= => GO TO DoubleReturn;
ENDCASE => GO TO PutbackReturn;
tokenKind ¬ $tokenPRAGMA;
DO
SELECT NextChar[ !
IO.EndOfStream =>
GO
TO Return]
FROM
'> =>
IF prev = '*
THEN {
IF (depth ¬ depth-1) = 0
THEN
GO
TO Return};
Must include the trailing *> in the pragma
'* => IF prev = '< THEN {depth ¬ depth+1; char ¬ 'x};
ENDCASE;
prev ¬ char;
ENDLOOP;
};
IN ['a .. 'z] => {
identifier
tokenKind ¬ $tokenID;
DO
SELECT NextChar[ !
IO.EndOfStream =>
GO
TO Return]
FROM
IN ['a..'z], IN ['0..'9], '← => NULL;
ENDCASE => GO TO PutbackReturn;
ENDLOOP;
};
IN ['0 .. '9] => {
numeric literal, this gets hairy
tokenKind ¬ $tokenDECIMAL;
WHILE NextChar[ ! IO.EndOfStream => GO TO Return] IN ['0..'9] DO ENDLOOP;
SELECT Ascii.Lower[char]
FROM
'. => {
IF NextChar[ !
IO.EndOfStream =>
GO
TO Invalid]
IN ['0 .. '9]
THEN {
-- REAL
tokenKind ¬ $tokenREAL;
AcceptRealTail[]; GO TO Return }
ELSE {
-- DECIMAL followed by dotdot
PutbackChar[]; GO TO PutbackReturn }
};
'← => {
tokenKind ¬ $tokenBASED;
DO
SELECT NextChar[ !
IO.EndOfStream =>
GO
TO Return]
FROM
IN ['0 .. '9] => NULL;
IN ['a .. 'f] => NULL;
ENDCASE => GO TO PutbackReturn ENDLOOP;
};
ENDCASE => GO TO PutbackReturn;
EXITS Invalid => { error ¬ $numericLiteral; GO TO ErrorReturn }
};
'. => {
either a dotdot or a REAL or a dot
tokenKind ¬ $tokenSINGLE;
SELECT NextChar[ !
IO.EndOfStream =>
GO
TO Return]
FROM
'. => GO TO DoubleReturn; -- dotdot
ENDCASE => GO TO PutbackReturn; -- dot
};
',, ';, '#, '+, '-, '*, '/, '^, '&, '), '[, '], '{, '}, '| =>
GO TO SingleReturn;
'\' => {
CHAR literal
tokenKind ¬ $tokenCHAR;
SELECT NextChar[ !
IO.EndOfStream =>
GO
TO Illegal]
FROM
'\\ => IF NOT AcceptExtendedChar[] THEN GO TO ErrorReturn;
'\' => GO TO Illegal;
ENDCASE => NULL;
IF NextChar[ ! IO.EndOfStream => GO TO Illegal] # '\' THEN GO TO Illegal;
EXITS Illegal => { error ¬ $charLiteral; GO TO ErrorReturn };
};
'\" => {
TEXT literal
tokenKind ¬ $tokenTEXT;
DO
c:
CHAR ¬ NextChar[
! IO.EndOfStream => GO TO Illegal];
SELECT c
FROM
'\" => GO TO Return;
'\\ => IF NOT AcceptExtendedChar[] THEN GO TO ErrorReturn;
ENDCASE => NULL;
ENDLOOP;
EXITS Illegal => { error ¬ $stringLiteral; GO TO ErrorReturn };
};
'= => {
either '=' or '=>'
tokenKind ¬ $tokenSINGLE;
SELECT NextChar[ !
IO.EndOfStream =>
GO
TO Return]
FROM
'> => GO TO DoubleReturn;
ENDCASE => GO TO PutbackReturn;
};
'>, ': => {
either '>' or '>='
tokenKind ¬ $tokenSINGLE;
SELECT NextChar[ !
IO.EndOfStream =>
GO
TO Return]
FROM
'= => GO TO DoubleReturn;
ENDCASE => GO TO PutbackReturn;
};
ENDCASE => {
error ¬ $singleChar;
GO TO ErrorReturn
};
EXITS
Return => { RETURN };
PutbackReturn => { PutbackChar[]; RETURN };
SingleReturn => { tokenKind ¬ $tokenSINGLE; RETURN };
DoubleReturn => { tokenKind ¬ $tokenDOUBLE; RETURN };
EOFReturn => { tokenKind ¬ $tokenEOF; RETURN };
ErrorReturn => { tokenKind ¬ $tokenERROR; RETURN };