home *** CD-ROM | disk | FTP | other *** search
Lex Description | 1992-09-19 | 16.6 KB | 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;
-
-