home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
pascal
/
compcomp
/
tpyacc
/
scanner.l
< prev
next >
Wrap
Text File
|
1992-09-19
|
17KB
|
535 lines
%{
(* ---------------------------------------------------------------- *)
(* *)
(* *)
(* (c) rr, 9.9., 19.9., *)
(* ---------------------------------------------------------------- *)
CONST
HexBase = 16;
DecBase = 10;
BinBase = 2;
OctBase = 8;
PROCEDURE MakeInt (S: STRING; FixBase: BYTE);
CONST
Values: ARRAY [0..15] OF CHAR =
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F');
VAR
i: INTEGER;
v: LONGINT;
Error: BOOLEAN;
Base: LONGINT;
FUNCTION Index (c: CHAR): BYTE;
VAR j, i: BYTE;
BEGIN
j := 16;
i := 0;
FOR i := 0 TO 15 DO
IF UpCase (c) = Values [i] THEN
j := i;
IF j > 15 THEN
Error := TRUE; { Zeichen ungültig ! }
Index := j;
END;
BEGIN
Error := FALSE;
Base := FixBase;
v := Index (s [Length (s)]) * 1;
FOR i := Length (S)-1 DOWNTO 1 DO BEGIN
v := v + Index (s [i]) * Base;
Base := Base * FixBase;
END;
IF NOT Error THEN BEGIN
yylVal.yyInteger := v;
Return (UNSIGNED_INTEGER);
END ELSE BEGIN
Writeln ('Error: Number too big');
Return (ILLEGAL);
END;
END;
PROCEDURE Commenteof;
BEGIN
Writeln ('Unexpected EOF inside Comment at line ', yyLineNo);
END;
FUNCTION Upper (Str: STRING): STRING;
VAR i: INTEGER;
BEGIN
FOR i := 1 TO Length (str) DO
str [i] := UpCase (str [i]);
Upper := Str;
END;
FUNCTION isKeyword (ID: STRING; VAR Token: INTEGER): BOOLEAN;
CONST
idLen = 20;
TYPE
Ident = STRING [idLen];
CONST
NoOfKeywords = 57;
KeyWords: ARRAY [1..NoOfKeywords] of Ident = (
'ABSOLUTE', 'AND', 'ARRAY', 'ASM',
'ASSEMBLER', 'BEGIN', 'CASE', 'CONST',
'CONSTRUCTOR', 'DESTRUCTOR', 'DIV', 'DO',
'DOWNTO', 'ELSE', 'END', 'EXTERNAL',
'FAR', 'FILE', 'FOR', 'FORWARD',
'FUNCTION', 'GOTO', 'IF', 'IMPLEMENTATION',
'IN', 'INLINE', 'INTERFACE', 'INTERRUPT',
'LABEL', 'MOD', 'NEAR', 'NIL',
'NOT', 'OBJECT', 'OF', 'OR',
'PACKED', 'PRIVATE', 'PROCEDURE', 'PROGRAM',
'RECORD', 'REPEAT', 'SET', 'SHL',
'SHR', 'STRING', 'THEN', 'TO',
'TYPE', 'UNIT', 'UNTIL', 'USES',
'VAR', 'VIRTUAL', 'WHILE', 'WITH',
'XOR');
KeywordTokens: ARRAY [1..NoOfKeywords] OF INTEGER = (
_ABSOLUTE_, _AND_, _ARRAY_, _ASM_,
_ASSEMBLER_, _BEGIN_, _CASE_, _CONST_,
_CONSTRUCTOR_, _DESTRUCTOR_, _DIV_, _DO_,
_DOWNTO_, _ELSE_, _END_, _EXTERNAL_,
_FAR_, _FILE_, _FOR_, _FORWARD_,
_FUNCTION_, _GOTO_, _IF_, _IMPLEMENTATION_,
_IN_, _INLINE_, _INTERFACE_, _INTERRUPT_,
_LABEL_, _MOD_, _NEAR_, _NIL_,
_NOT_, _OBJECT_, _OF_, _OR_,
_PACKED_, _PRIVATE_, _PROCEDURE_, _PROGRAM_,
_RECORD_, _REPEAT_, _SET_, _SHL_,
_SHR_, _STRING_, _THEN_, _TO_,
_TYPE_, _UNIT_, _UNTIL_, _USES_,
_VAR_, _VIRTUAL_, _WHILE_, _WITH_,
_XOR_);
VAR m, n, k: INTEGER;
BEGIN
id := Upper (id);
(* Binäre Suche (Bisektionssuche): *)
m := 1; n := NoOfKeywords;
WHILE m <= n DO BEGIN
k := m + (n-m) DIV 2;
IF id = KeyWords [k] THEN BEGIN
isKeyword := TRUE;
Token := KeywordTokens[k];
Exit;
END ELSE
IF id > Keywords [k] THEN
m := k+1
ELSE
n := k-1
END;
isKeyword := FALSE;
END;
FUNCTION isAssemblerKeyword (ID: STRING; VAR Token: INTEGER): BOOLEAN;
CONST
idLen = 10;
TYPE
Ident = STRING [idLen];
CONST
NoOfKeywords = 181;
KeyWords: ARRAY [1..NoOfKeywords] of Ident = (
'LOCK', 'REP', 'REPE', 'REPZ', 'REPNE',
'REPNZ', 'SEGCS', 'SEGDS', 'SEGES', 'SEGSS',
'DB', 'DW', 'DD', 'AH', 'DH',
'DX', 'OR', 'ST', 'AL', 'CL',
'ES', 'PTR', 'TBYTE', 'AND', 'CS',
'FAR', 'QWORD', 'TYPE', 'AX', 'CX',
'HIGH', 'SEG', 'WORD', 'BH', 'DH',
'LOW', 'SHL', 'XOR', 'BL', 'DI',
'MOD', 'SHR', 'BP', 'DL', 'NEAR',
'SI', 'BX', 'DS', 'NOT', 'SP',
'BYTE', 'DWORD', 'OFFSET', 'SS', 'CODE',
'DATA', 'RESULT', 'AAA', 'AAD', 'AAM',
'AAS', 'ADC', 'ADD', 'AND', 'BOUND',
'CALL', 'CBW', 'CDQ', 'CLC', 'CLD',
'CLI', 'CMC', 'CMP', 'CMPS', 'CMPSB',
'CMPSW', 'DAA', 'DAS', 'DEC', 'DIV',
'ENTER', 'HLT', 'IDIV', 'IMUL', 'IN',
'INC', 'INS', 'INSB', 'INSW', 'INT',
'INTO', 'IRET', 'JA', 'JAE', 'JB',
'JBE', 'JC', 'JCXZ', 'JE', 'JZ',
'JG', 'JGE', 'JL', 'JLE', 'JNA',
'JNAE', 'JNB', 'JNBE', 'JNC', 'JNE',
'JNG', 'JNGE', 'JNL', 'JNLE', 'JNO',
'JNP', 'JNS', 'JNZ', 'JO', 'JP',
'JPE', 'JPO', 'JS', 'JZ', 'JMP',
'LAHF', 'LEA', 'LEAVE', 'LOCK', 'LODS',
'LODSB', 'LODSW', 'LOOP', 'LOOPE', 'LOOPZ',
'LOOPNE', 'LOOPNZ', 'MOV', 'MOVS', 'MOVSB',
'MOVSW', 'MUL', 'NEG', 'NOP', 'NOT',
'OR', 'OUT', 'OUTS', 'OUTSB', 'OUTSW',
'POP', 'POPF', 'PUSH', 'PUSHF', 'RCL',
'RCR', 'ROL', 'ROR', 'RET', 'SAHF',
'SAL', 'SAR', 'SHL', 'SHR', 'SBB',
'SCAS', 'SCASB', 'SCASW', 'STC', 'STD',
'STI', 'STOS', 'STOSB', 'STOSW', 'SUB',
'TEST', 'WAIT', 'XCHG', 'XLAT', 'XLATB',
'XOR');
KeywordTokens: ARRAY [1..NoOfKeywords] OF INTEGER = (
_LOCK_, _REP_, _REPE_, _REPZ_, _REPNE_,
_REPNZ_, _SEGCS_, _SEGDS_, _SEGES_, _SEGSS_,
_DB_, _DW_, _DD_, _AH_, _DH_,
_DX_, _OR_, _ST_, _AL_, _CL_,
_ES_, _PTR_, _TBYTE_, _AND_, _CS_,
_FAR_, _QWORD_, _TYPE_, _AX_, _CX_,
_HIGH_, _SEG_, _WORD_, _BH_, _DH_,
_LOW_, _SHL_, _XOR_, _BL_, _DI_,
_MOD_, _SHR_, _BP_, _DL_, _NEAR_,
_SI_, _BX_, _DS_, _NOT_, _SP_,
_BYTE_, _DWORD_, _OFFSET_, _SS_, _CODE_,
_DATA_, _RESULT_, _AAA_, _AAD_, _AAM_,
_AAS_, _ADC_, _ADD_, _AND_, _BOUND_,
_CALL_, _CBW_, _CDQ_, _CLC_, _CLD_,
_CLI_, _CMC_, _CMP_, _CMPS_, _CMPSB_,
_CMPSW_, _DAA_, _DAS_, _DEC_, _DIV_,
_ENTER_, _HLT_, _IDIV_, _IMUL_, _IN_,
_INC_, _INS_, _INSB_, _INSW_, _INT_,
_INTO_, _IRET_, _JA_, _JAE_, _JB_,
_JBE_, _JC_, _JCXZ_, _JE_, _JZ_,
_JG_, _JGE_, _JL_, _JLE_, _JNA_,
_JNAE_, _JNB_, _JNBE_, _JNC_, _JNE_,
_JNG_, _JNGE_, _JNL_, _JNLE_, _JNO_,
_JNP_, _JNS_, _JNZ_, _JO_, _JP_,
_JPE_, _JPO_, _JS_, _JZ_, _JMP_,
_LAHF_, _LEA_, _LEAVE_, _LOCK_, _LODS_,
_LODSB_, _LODSW_, _LOOP_, _LOOPE_, _LOOPZ_,
_LOOPNE_, _LOOPNZ_, _MOV_, _MOVS_, _MOVSB_,
_MOVSW_, _MUL_, _NEG_, _NOP_, _NOT_,
_OR_, _OUT_, _OUTS_, _OUTSB_, _OUTSW_,
_POP_, _POPF_, _PUSH_, _PUSHF_, _RCL_,
_RCR_, _ROL_, _ROR_, _RET_, _SAHF_,
_SAL_, _SAR_, _SHL_, _SHR_, _SBB_,
_SCAS_, _SCASB_, _SCASW_, _STC_, _STD_,
_STI_, _STOS_, _STOSB_, _STOSW_, _SUB_,
_TEST_, _WAIT_, _XCHG_, _XLAT_, _XLATB_,
_XOR_);
VAR m, n, k: INTEGER;
BEGIN
id := Upper (id);
m := 1; n := NoOfKeywords;
WHILE m <= n DO BEGIN
k := m + (n-m) DIV 2;
IF id = KeyWords [k] THEN BEGIN
isAssemblerKeyword := TRUE;
Token := KeywordTokens [k];
Exit;
END ELSE
IF id > Keywords [k] THEN
m := k+1
ELSE
n := k-1
END;
isAssemblerKeyword := FALSE;
END;
%}
%Start Normal
%Start Comment
%Start String1
%Start String2
%Start asmString1
%Start asmString2
%Start asmState
%Start asmComment
letter [A-Za-z_]
digit [0-9]
hexdigit [0-9A-Fa-f]
identifier {letter}({letter}|{digit})*
integer ({digit}+|\${hexdigit}+)
sign [\+\-]
exp [Ee]{sign}?{digit}+
real {digit}+(\.{digit}+)?{exp}?
special [\+\-*/=<>,():;@\^\[\]"."]
white [\1-\40]
eof \0
asmLabel @+(@|{letter}|{digit})*
asmBinary [01]+[Bb]
asmOctal [0-7]+[Oo]
asmHex {digit}{hexdigit}+[Hh]
asmWhite [\1-\11\13-\40]
asmSpecial ({special}|&)
%%
VAR
Result: INTEGER;
EndText: STRING [2];
c: CHAR;
KW: INTEGER;
s: STRING;
i: INTEGER;
cs: STRING [2];
<Normal>'
BEGIN
s := '';
Start (String2);
END;
<Normal>#
BEGIN
s := '';
Start (String1);
Unget_Char (yyText [1]);
END;
<String1>'
Start (String2);
<String1>#{integer}
BEGIN { #123 oder #$12 im String enthalten }
Delete (yyText, 1, 1);
Val (yyText, i, Result);
IF Result = 0 THEN
s := s + Char (i)
ELSE
Write (' Error in integer constant ');
END;
<String1>.
BEGIN
Start (Normal);
Return (STRING_CONST);
UnGet_Char (yytext [1]);
Write (''''+s+'''');
END;
<String2>"''"
s := s+'''';
<String2>'
Start (String1);
<asmState>'
BEGIN
Start (asmString1); s := '';
END;
<asmString1>"''"
s := s+'''';
<asmString1>'
BEGIN
Start (asmState);
Return (STRING_CONST);
Write (''''+s+'''');
END;
<asmState>\"
BEGIN
Start (asmString2); s := '';
END;
<asmString2>""""
s := s+'"';
<asmString2>\"
BEGIN
Start (asmState);
Return (STRING_CONST);
Write ('"'+s+'"');
END;
<String2,asmString1,asmString2>\n
BEGIN
Writeln ('String exceeds line'); Halt;
END;
<String2,asmString1,asmString2>.
s := s + yyText;
<Normal>"(*"|"{"
BEGIN
cs := yyText;
Write (yyText);
Start (Comment);
END;
<Comment>"*)"|"}"
BEGIN
IF ((yyText = '}') AND (cs = '{')) OR
((yyText = '*)') AND (cs = '(*')) THEN BEGIN
Write (yyText);
Start (Normal);
END;
END;
<asmState>"(*"|"{"
BEGIN
Write (yyText);
Start (asmComment);
END;
<asmComment>"*)"|"}"
BEGIN
IF ((yyText = '}') AND (cs = '{')) OR
((yyText = '*)') AND (cs = '(*')) THEN BEGIN
Write (yyText);
Start (asmState);
Return (ASM_Comment);
END;
END;
<asmComment,Comment>\0
BEGIN
Start (Normal);
CommentEof;
END;
<asmComment,Comment>.
Write (yyText);
<asmState>{identifier}
BEGIN
Write (yyText);
IF isAssemblerKeyword (yyText, KW) THEN
Return (KW)
ELSE
Return (ID);
IF Upper (yyText) = 'END' THEN
Start (Normal);
END;
<asmState>{asmLabel}
BEGIN
Return (ASM_LABEL);
Write (yytext);
END;
<asmState>{asmBinary}
BEGIN
Write (yyText);
Dec (Byte (yyText [0]));
MakeInt (yyText, BinBase);
END;
<asmState>{asmOctal}
BEGIN
Write (yyText);
Dec (Byte (yyText [0]));
MakeInt (yyText, OctBase);
END;
<asmState>{asmHex}
BEGIN
Write (yyText);
Dec (Byte (yyText [0]));
MakeInt (yyText, HexBase);
END;
<asmState>\n
BEGIN
Writeln;
Return (ASM_SEPERATOR);
END;
<asmState>;
BEGIN
Write (';');
Return (ASM_SEPERATOR);
END;
<asmState>{asmWhite}
Write (yyText);
<asmState>{asmSpecial}
BEGIN
ReturnC (yyText [1]);
Write (yyText);
END;
<asmState,Normal>{integer}
BEGIN
Val (yyText, yylVal.yyInteger, Result);
Write (yyText);
IF Result=0 THEN
Return (UNSIGNED_INTEGER)
ELSE
Return (ILLEGAL);
END;
<asmState>.
BEGIN
Write ('Illegal character: ', yyText);
Return (ILLEGAL);
END;
<Normal>{real}
BEGIN
Val (yyText, yylVal.yyReal, Result);
Write (yyText);
IF Result=0 THEN
Return (UNSIGNED_REAL)
ELSE
Return (ILLEGAL);
END;
<Normal>{identifier}
BEGIN
Write (yyText);
IF isKeyword (yyText, KW) THEN
Return (KW)
ELSE
Return (ID);
IF Upper (yyText) = 'ASM' THEN
Start (asmState);
END;
<Normal>".."
BEGIN
Write (yyText);
Return (DOTDOT);
END;
<Normal>":="
BEGIN
Write (yyText);
Return (DEFEQ);
END;
<Normal>"<="
BEGIN
Write (yyText);
Return (LEQ);
END;
<Normal>"<>"
BEGIN
Write (yyText);
Return (NEQ);
END;
<Normal>">="
BEGIN
Write (yyText);
Return (GEQ);
END;
<Normal>"(."
BEGIN
Write (yyText);
yyText := '[';
ReturnC ('[');
END;
<Normal>".)"
BEGIN
Write (yyText);
yyText := ']';
ReturnC (']');
END;
<Normal>{eof}
BEGIN
Write (yyText);
Return (0);
END;
<Normal>{white}
BEGIN
IF yyText = #10 THEN
Writeln
ELSE
Write (yyText);
END;
<Normal>{special}
BEGIN
ReturnC (yyText [1]);
Write (yyText);
END;
<Normal>.
BEGIN
Write ('Illegal character: ', yyText);
Return (ILLEGAL);
END;