оптимизированный лексер

This commit is contained in:
AntKrotov committed 2021-02-05 14:27:04 +03:00
1 parent 98db9d4dc9
commit 8234828dfc
13 files changed
+130 -124

No files matched your search

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -75,8 +75,8 @@ UTF-8 с BOM-сигнатурой.
SET множество из целых чисел {0 .. 15} 2
BYTE 0 .. 255 1
2. Максимальная длина идентификаторов - 1024 символов
3. Максимальная длина строковых констант - 1024 символов (UTF-8)
2. Максимальная длина идентификаторов - 255 символов
3. Максимальная длина строковых констант - 511 символов (UTF-8)
4. Максимальная размерность открытых массивов - 5
5. Процедура NEW заполняет нулями выделенный блок памяти
6. Локальные переменные инициализируются нулями
+2 -2
View File
@@ -78,8 +78,8 @@ UTF-8 с BOM-сигнатурой.
BYTE 0 .. 255 1
WCHAR символ юникода (0X .. 0FFFFX) 2
2. Максимальная длина идентификаторов - 1024 символов
3. Максимальная длина строковых констант - 1024 символов (UTF-8)
2. Максимальная длина идентификаторов - 255 символов
3. Максимальная длина строковых констант - 511 символов (UTF-8)
4. Максимальная размерность открытых массивов - 5
5. Процедура NEW заполняет нулями выделенный блок памяти
6. Локальные переменные инициализируются нулями
+2 -2
View File
@@ -94,8 +94,8 @@ UTF-8 с BOM-сигнатурой.
BYTE 0 .. 255 1
WCHAR символ юникода (0X .. 0FFFFX) 2
2. Максимальная длина идентификаторов - 1024 символов
3. Максимальная длина строковых констант - 1024 символов (UTF-8)
2. Максимальная длина идентификаторов - 255 символов
3. Максимальная длина строковых констант - 511 символов (UTF-8)
4. Максимальная размерность открытых массивов - 5
5. Процедура NEW заполняет нулями выделенный блок памяти
6. Глобальные и локальные переменные инициализируются нулями
+2 -2
View File
@@ -86,8 +86,8 @@ UTF-8 с BOM-сигнатурой.
BYTE 0 .. 255 1
WCHAR символ юникода (0X .. 0FFFFX) 2
2. Максимальная длина идентификаторов - 1024 символов
3. Максимальная длина строковых констант - 1024 символов (UTF-8)
2. Максимальная длина идентификаторов - 255 символов
3. Максимальная длина строковых констант - 511 символов (UTF-8)
4. Максимальная размерность открытых массивов - 5
5. Процедура NEW заполняет нулями выделенный блок памяти
6. Глобальные и локальные переменные инициализируются нулями
+3 -2
View File
@@ -1,7 +1,7 @@
(*
BSD 2-Clause License
Copyright (c) 2018-2020, Anton Krotov
Copyright (c) 2018-2021, Anton Krotov
All rights reserved.
*)
@@ -25,6 +25,7 @@ BEGIN
CASE warning OF
|0: C.StringLn("passing a string value as a fixed array")
|1: C.StringLn("endless FOR loop")
|2: C.StringLn("identifier too long")
END
END WarningMsg;
@@ -43,7 +44,7 @@ BEGIN
| 3: str := "unclosed string"
| 4: str := "illegal character"
| 5: str := "string too long"
| 6: str := "identifier too long"
| 7: str := "number too long"
| 8..12: str := "number too large"
| 13: str := "real numbers not supported"
+5 -5
View File
@@ -166,13 +166,13 @@ TYPE
EXPORT_PROC* = POINTER TO RECORD (LISTS.ITEM)
label*: INTEGER;
name*: SCAN.LEXSTR
name*: SCAN.IDSTR
END;
IMPORT_LIB* = POINTER TO RECORD (LISTS.ITEM)
name*: SCAN.LEXSTR;
name*: SCAN.TEXTSTR;
procs*: LISTS.LIST
END;
@@ -181,7 +181,7 @@ TYPE
label*: INTEGER;
lib*: IMPORT_LIB;
name*: SCAN.LEXSTR;
name*: SCAN.TEXTSTR;
count: INTEGER
END;
@@ -1107,7 +1107,7 @@ BEGIN
END fname;
PROCEDURE AddExp* (label: INTEGER; name: SCAN.LEXSTR);
PROCEDURE AddExp* (label: INTEGER; name: SCAN.IDSTR);
VAR
exp: EXPORT_PROC;
@@ -1119,7 +1119,7 @@ BEGIN
END AddExp;
PROCEDURE AddImp* (dll, proc: SCAN.LEXSTR): IMPORT_PROC;
PROCEDURE AddImp* (dll, proc: SCAN.TEXTSTR): IMPORT_PROC;
VAR
lib: IMPORT_LIB;
p: IMPORT_PROC;
+18 -17
View File
@@ -233,7 +233,7 @@ BEGIN
_in := TRUE;
Next(parser);
IF parser.sym = SCAN.lxSTRING THEN
STRINGS.trim(parser.lex.s, fname)
STRINGS.trim(parser.lex.string.s, fname)
ELSIF parser.sym = SCAN.lxCHAR THEN
fname[0] := CHR(ARITH.Int(parser.lex.value));
fname[1] := 0X
@@ -343,7 +343,7 @@ END QIdent;
PROCEDURE strcmp* (VAR v: ARITH.VALUE; v2: ARITH.VALUE; operator: INTEGER);
VAR
str: SCAN.LEXSTR;
str: SCAN.TEXTSTR;
string1, string2: SCAN.STRING;
bool: BOOLEAN;
@@ -531,25 +531,26 @@ VAR
res, sf: INTEGER;
BEGIN
IF parser.lex.s = "stdcall" THEN
checklex(parser, SCAN.lxIDENT);
IF parser.lex.ident.s = "stdcall" THEN
sf := PROG.sf_stdcall
ELSIF parser.lex.s = "cdecl" THEN
ELSIF parser.lex.ident.s = "cdecl" THEN
sf := PROG.sf_cdecl
ELSIF parser.lex.s = "ccall" THEN
ELSIF parser.lex.ident.s = "ccall" THEN
sf := PROG.sf_ccall
ELSIF parser.lex.s = "win64" THEN
ELSIF parser.lex.ident.s = "win64" THEN
sf := PROG.sf_win64
ELSIF parser.lex.s = "systemv" THEN
ELSIF parser.lex.ident.s = "systemv" THEN
sf := PROG.sf_systemv
ELSIF parser.lex.s = "windows" THEN
ELSIF parser.lex.ident.s = "windows" THEN
sf := PROG.sf_windows
ELSIF parser.lex.s = "linux" THEN
ELSIF parser.lex.ident.s = "linux" THEN
sf := PROG.sf_linux
ELSIF parser.lex.s = "code" THEN
ELSIF parser.lex.ident.s = "code" THEN
sf := PROG.sf_code
ELSIF parser.lex.s = "oberon" THEN
ELSIF parser.lex.ident.s = "oberon" THEN
sf := PROG.sf_oberon
ELSIF parser.lex.s = "noalign" THEN
ELSIF parser.lex.ident.s = "noalign" THEN
sf := PROG.sf_noalign
ELSE
check1(FALSE, parser, 124)
@@ -611,11 +612,11 @@ END sysflag;
PROCEDURE procflag (parser: PARSER; VAR _import: IL.IMPORT_PROC; isProc: BOOLEAN): INTEGER;
VAR
call: INTEGER;
dll, proc: SCAN.LEXSTR;
dll, proc: SCAN.TEXTSTR;
pos: POSITION;
PROCEDURE getStr (parser: PARSER; VAR name: SCAN.LEXSTR);
PROCEDURE getStr (parser: PARSER; VAR name: SCAN.TEXTSTR);
VAR
pos: POSITION;
str: ARITH.VALUE;
@@ -996,7 +997,7 @@ VAR
proc := IdentDef(parser, PROG.idIMP, name);
proc._import := _import;
IF _import.name = "" THEN
_import.name := name.s
COPY(name.s, _import.name)
END;
PROG.program.procs.last(PROG.PROC)._import := _import
ELSE
@@ -1240,7 +1241,7 @@ BEGIN
ExpectSym(parser, SCAN.lxIDENT);
IF ~parser.main THEN
check1(parser.lex.s = parser.modname, parser, 23)
check1(parser.lex.ident.s = parser.modname, parser, 23)
END;
unit := PROG.newUnit(parser.lex.ident);
@@ -1300,7 +1301,7 @@ BEGIN
checklex(parser, SCAN.lxEND);
ExpectSym(parser, SCAN.lxIDENT);
check1(parser.lex.s = unit.name.s, parser, 25);
check1(parser.lex.ident.s = unit.name.s, parser, 25);
ExpectSym(parser, SCAN.lxPOINT)
END;
+6 -6
View File
@@ -648,10 +648,10 @@ END getUnit;
PROCEDURE enterStTypes (unit: UNIT);
PROCEDURE enter (unit: UNIT; nameStr: SCAN.LEXSTR; _type: _TYPE);
PROCEDURE enter (unit: UNIT; nameStr: SCAN.IDSTR; _type: _TYPE);
VAR
ident: IDENT;
upper: SCAN.LEXSTR;
upper: SCAN.IDSTR;
name: SCAN.IDENT;
BEGIN
@@ -688,10 +688,10 @@ END enterStTypes;
PROCEDURE enterStProcs (unit: UNIT);
PROCEDURE Enter (unit: UNIT; nameStr: SCAN.LEXSTR; nfunc, tfunc: INTEGER);
PROCEDURE Enter (unit: UNIT; nameStr: SCAN.IDSTR; nfunc, tfunc: INTEGER);
VAR
ident: IDENT;
upper: SCAN.LEXSTR;
upper: SCAN.IDSTR;
name: SCAN.IDENT;
BEGIN
@@ -1080,10 +1080,10 @@ VAR
name: SCAN.IDENT;
PROCEDURE EnterProc (sys: UNIT; nameStr: SCAN.LEXSTR; idtyp, proc: INTEGER);
PROCEDURE EnterProc (sys: UNIT; nameStr: SCAN.IDSTR; idtyp, proc: INTEGER);
VAR
ident: IDENT;
upper: SCAN.LEXSTR;
upper: SCAN.IDSTR;
name: SCAN.IDENT;
BEGIN
+87 -83
View File
@@ -12,7 +12,9 @@ IMPORT TXT := TEXTDRV, ARITH, S := STRINGS, ERRORS, LISTS;
CONST
LEXLEN = 1024;
NUMLEN = 256;
IDLEN = 256;
TEXTLEN = 512;
lxUNDEF* = 0; lxIDENT* = 1; lxINTEGER* = 2; lxHEX* = 3;
lxCHAR* = 4; lxFLOAT* = 5; lxSTRING* = 6; lxCOMMENT* = 7;
@@ -39,31 +41,32 @@ CONST
lxWHILE* = 83;
lxERROR01* = -1; lxERROR02* = -2; lxERROR03* = -3; lxERROR04* = -4;
lxERROR05* = -5; lxERROR06* = -6; lxERROR07* = -7; lxERROR08* = -8;
lxERROR05* = -5; (*lxERROR06* = -6;*) lxERROR07* = -7; lxERROR08* = -8;
lxERROR09* = -9; lxERROR10* = -10; lxERROR11* = -11; lxERROR12* = -12;
lxERROR13* = -13;
TYPE
LEXSTR* = ARRAY LEXLEN OF CHAR;
TEXTSTR* = ARRAY TEXTLEN OF CHAR;
IDSTR* = ARRAY IDLEN OF CHAR;
DEF = POINTER TO RECORD (LISTS.ITEM)
ident: LEXSTR
ident: IDSTR
END;
STRING* = POINTER TO RECORD (LISTS.ITEM)
s*: LEXSTR;
s*: TEXTSTR;
offset*, offsetW*, hash: INTEGER
END;
IDENT* = RECORD
s*: LEXSTR;
s*: IDSTR;
hash*: INTEGER
END;
@@ -76,17 +79,12 @@ TYPE
LEX* = RECORD
s*: LEXSTR;
length*: INTEGER;
sym*: INTEGER;
hash: INTEGER;
pos*: POSITION;
ident*: IDENT;
string*: STRING;
value*: ARITH.VALUE;
error*: INTEGER;
over: BOOLEAN
error*: INTEGER
END;
@@ -136,7 +134,7 @@ BEGIN
END checkKW;
PROCEDURE enterStr* (s: LEXSTR): STRING;
PROCEDURE enterStr* (s: TEXTSTR): STRING;
VAR
str, res: STRING;
hash: INTEGER;
@@ -158,7 +156,7 @@ BEGIN
res.s := s;
res.offset := -1;
res.offsetW := -1;
res.hash := S.HashStr(s);
res.hash := hash;
LISTS.push(strings, res)
END
@@ -166,18 +164,6 @@ BEGIN
END enterStr;
PROCEDURE putchar (VAR lex: LEX; c: CHAR);
BEGIN
IF lex.length < LEXLEN - 1 THEN
lex.s[lex.length] := c;
INC(lex.length);
lex.s[lex.length] := 0X
ELSE
lex.over := TRUE
END
END putchar;
PROCEDURE nextc (text: TXT.TEXT): CHAR;
BEGIN
TXT.next(text)
@@ -185,69 +171,91 @@ BEGIN
END nextc;
PROCEDURE setIdent* (VAR ident: IDENT; s: LEXSTR);
PROCEDURE setIdent* (VAR ident: IDENT; s: IDSTR);
BEGIN
ident.s := s;
ident.hash := S.HashStr(s);
ident.hash := S.HashStr(s)
END setIdent;
PROCEDURE ident (text: TXT.TEXT; VAR lex: LEX);
VAR
c: CHAR;
i: INTEGER;
BEGIN
c := text.peak;
ASSERT(S.letter(c));
WHILE S.letter(c) OR S.digit(c) DO
putchar(lex, c);
i := 0;
WHILE (i < IDLEN - 1) & (S.letter(c) OR S.digit(c)) DO
lex.ident.s[i] := c;
INC(i);
c := nextc(text)
END;
IF lex.over THEN
lex.sym := lxERROR06
ELSE
setIdent(lex.ident, lex.s);
lex.sym := checkKW(lex.ident)
END
lex.ident.s[i] := 0X;
lex.ident.hash := S.HashStr(lex.ident.s);
lex.sym := checkKW(lex.ident);
IF S.letter(c) OR S.digit(c) THEN
ERRORS.WarningMsg(lex.pos.line, lex.pos.col, 2);
WHILE S.letter(c) OR S.digit(c) DO
c := nextc(text)
END
END
END ident;
PROCEDURE number (text: TXT.TEXT; VAR lex: LEX);
TYPE
NUMSTR = ARRAY NUMLEN OF CHAR;
VAR
c: CHAR;
hex: BOOLEAN;
error, sym: INTEGER;
error, sym, i: INTEGER;
num: NUMSTR;
PROCEDURE push (VAR num: NUMSTR; VAR i: INTEGER; c: CHAR);
BEGIN
IF i < NUMLEN - 1 THEN
num[i] := c;
INC(i)
END
END push;
BEGIN
c := text.peak;
ASSERT(S.digit(c));
i := 0;
error := 0;
sym := lxINTEGER;
hex := FALSE;
WHILE S.digit(c) DO
putchar(lex, c);
push(num, i, c);
c := nextc(text)
END;
WHILE S.hexdigit(c) DO
putchar(lex, c);
push(num, i, c);
c := nextc(text);
hex := TRUE
END;
IF c = "H" THEN
putchar(lex, c);
push(num, i, c);
TXT.next(text);
sym := lxHEX
ELSIF c = "X" THEN
putchar(lex, c);
push(num, i, c);
TXT.next(text);
sym := lxCHAR
@@ -260,7 +268,7 @@ BEGIN
c := nextc(text);
IF c # "." THEN
putchar(lex, ".");
push(num, i, ".");
sym := lxFLOAT
ELSE
sym := lxINTEGER;
@@ -269,22 +277,22 @@ BEGIN
END;
WHILE S.digit(c) DO
putchar(lex, c);
push(num, i, c);
c := nextc(text)
END;
IF c = "E" THEN
putchar(lex, c);
push(num, i, c);
c := nextc(text);
IF (c = "+") OR (c = "-") THEN
putchar(lex, c);
push(num, i, c);
c := nextc(text)
END;
IF S.digit(c) THEN
WHILE S.digit(c) DO
putchar(lex, c);
push(num, i, c);
c := nextc(text)
END
ELSE
@@ -300,16 +308,19 @@ BEGIN
END;
IF lex.over & (sym >= 0) THEN
IF (i = NUMLEN - 1) & (sym >= 0) THEN
sym := lxERROR07
END;
IF sym = lxINTEGER THEN
ARITH.iconv(lex.s, lex.value, error)
num[i] := 0X;
ARITH.iconv(num, lex.value, error)
ELSIF (sym = lxHEX) OR (sym = lxCHAR) THEN
ARITH.hconv(lex.s, lex.value, error)
num[i] := 0X;
ARITH.hconv(num, lex.value, error)
ELSIF sym = lxFLOAT THEN
ARITH.fconv(lex.s, lex.value, error)
num[i] := 0X;
ARITH.fconv(num, lex.value, error)
END;
CASE error OF
@@ -328,36 +339,39 @@ END number;
PROCEDURE string (text: TXT.TEXT; VAR lex: LEX; quot: CHAR);
VAR
c: CHAR;
n: INTEGER;
i: INTEGER;
str: TEXTSTR;
BEGIN
c := nextc(text);
n := 0;
WHILE (c # quot) & (c # 0X) & ~text.eol & ~text.eof DO
putchar(lex, c);
i := 0;
WHILE (i < LEN(str) - 1) & (c # quot) & (c # 0X) & ~text.eol & ~text.eof DO
str[i] := c;
c := nextc(text);
INC(n)
INC(i)
END;
str[i] := 0X;
IF (i = LEN(str) - 1) & (c # quot) & (c # 0X) & ~text.eol & ~text.eof THEN
lex.sym := lxERROR05
END;
IF c = quot THEN
TXT.next(text);
IF lex.over THEN
lex.sym := lxERROR05
IF i # 1 THEN
lex.sym := lxSTRING
ELSE
IF n # 1 THEN
lex.sym := lxSTRING
ELSE
lex.sym := lxCHAR;
ARITH.setChar(lex.value, ORD(lex.s[0]))
END
lex.sym := lxCHAR;
ARITH.setChar(lex.value, ORD(str[0]))
END
ELSE
ELSIF lex.sym # lxERROR05 THEN
lex.sym := lxERROR03
END;
IF lex.sym = lxSTRING THEN
lex.string := enterStr(lex.s);
lex.string := enterStr(str);
lex.value.typ := ARITH.tSTRING;
lex.value.string := lex.string
END
@@ -402,15 +416,16 @@ BEGIN
END comment;
PROCEDURE delimiter (text: TXT.TEXT; VAR lex: LEX; c: CHAR);
PROCEDURE delimiter (text: TXT.TEXT; c: CHAR): INTEGER;
VAR
sym: INTEGER;
c0: CHAR;
BEGIN
putchar(lex, c);
c0 := c;
c := nextc(text);
CASE lex.s[0] OF
CASE c0 OF
|"+":
sym := lxPLUS
@@ -441,7 +456,6 @@ BEGIN
IF c = "." THEN
sym := lxRANGE;
putchar(lex, c);
TXT.next(text)
END
@@ -483,7 +497,6 @@ BEGIN
IF c = "=" THEN
sym := lxLE;
putchar(lex, c);
TXT.next(text)
END
@@ -492,7 +505,6 @@ BEGIN
IF c = "=" THEN
sym := lxGE;
putchar(lex, c);
TXT.next(text)
END
@@ -501,7 +513,6 @@ BEGIN
IF c = "=" THEN
sym := lxASSIGN;
putchar(lex, c);
TXT.next(text)
END
@@ -514,10 +525,9 @@ BEGIN
|"}":
sym := lxRCURLY
END;
lex.sym := sym
END
RETURN sym
END delimiter;
@@ -583,7 +593,7 @@ VAR
check(lex.sym = lxIDENT, text, lex, 22);
REPEAT
IF IsDef(lex.s) THEN
IF IsDef(lex.ident.s) THEN
skip := FALSE
END;
@@ -635,11 +645,8 @@ BEGIN
c := nextc(text)
END;
lex.s[0] := 0X;
lex.length := 0;
lex.pos.line := text.line;
lex.pos.col := text.col;
lex.over := FALSE;
IF S.letter(c) THEN
ident(text, lex)
@@ -648,7 +655,7 @@ BEGIN
ELSIF (c = '"') OR (c = "'") THEN
string(text, lex, c)
ELSIF delimiters[ORD(c)] THEN
delimiter(text, lex, c)
lex.sym := delimiter(text, c)
ELSIF c = "$" THEN
IF S.letter(nextc(text)) THEN
ident(text, lex);
@@ -675,12 +682,9 @@ BEGIN
ELSIF (c = 7FX) & upto THEN
upto := FALSE;
lex.sym := lxRANGE;
putchar(lex, ".");
putchar(lex, ".");
DEC(lex.pos.col);
TXT.next(text)
ELSE
putchar(lex, c);
TXT.next(text);
lex.sym := lxERROR04
END;
+2 -2
View File
@@ -2064,7 +2064,7 @@ VAR
pos: PARS.POSITION;
op: INTEGER;
e1: PARS.EXPR;
s, s1: SCAN.LEXSTR;
s, s1: SCAN.TEXTSTR;
plus, minus: BOOLEAN;
@@ -3261,7 +3261,7 @@ VAR
rtl: PROG.UNIT;
PROCEDURE getproc (rtl: PROG.UNIT; name: SCAN.LEXSTR; idx: INTEGER);
PROCEDURE getproc (rtl: PROG.UNIT; name: SCAN.IDSTR; idx: INTEGER);
VAR
id: PROG.IDENT;
ident: SCAN.IDENT;
+1 -1
View File
@@ -24,7 +24,7 @@ CONST
vMajor* = 1;
vMinor* = 50;
Date* = "2021-02-04";
Date* = "2021-02-05";
FILE_EXT* = ".ob07";
RTL_NAME* = "RTL";