Subversion Repositories Kolibri OS

Rev

Rev 7983 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7983 Rev 8097
Line 1... Line 1...
1
(*
1
(*
2
    BSD 2-Clause License
2
    BSD 2-Clause License
Line 3... Line 3...
3
 
3
 
4
    Copyright (c) 2018-2019, Anton Krotov
4
    Copyright (c) 2018-2020, Anton Krotov
5
    All rights reserved.
5
    All rights reserved.
Line 6... Line 6...
6
*)
6
*)
Line 7... Line 7...
7
 
7
 
Line 8... Line 8...
8
MODULE SCAN;
8
MODULE SCAN;
Line 9... Line 9...
9
 
9
 
Line 46... Line 46...
46
 
46
 
Line 47... Line 47...
47
TYPE
47
TYPE
Line -... Line 48...
-
 
48
 
-
 
49
    LEXSTR* = ARRAY LEXLEN OF CHAR;
-
 
50
 
-
 
51
    DEF = POINTER TO RECORD (LISTS.ITEM)
-
 
52
 
-
 
53
        ident: LEXSTR
48
 
54
 
Line 49... Line 55...
49
    LEXSTR* = ARRAY LEXLEN OF CHAR;
55
    END;
50
 
56
 
51
    IDENT* = POINTER TO RECORD (AVL.DATA)
57
    IDENT* = POINTER TO RECORD (AVL.DATA)
Line 86... Line 92...
86
 
92
 
Line 87... Line 93...
87
    delimiters: ARRAY 256 OF BOOLEAN;
93
    delimiters: ARRAY 256 OF BOOLEAN;
Line 88... Line 94...
88
 
94
 
-
 
95
    NewIdent: IDENT;
-
 
96
 
Line 89... Line 97...
89
    NewIdent: IDENT;
97
    upto, LowerCase, _if: BOOLEAN;
90
 
98
 
91
    upto: BOOLEAN;
99
    def: LISTS.LIST;
Line 164... Line 172...
164
 
172
 
165
PROCEDURE number (text: TXT.TEXT; VAR lex: LEX);
173
PROCEDURE number (text: TXT.TEXT; VAR lex: LEX);
166
VAR
174
VAR
167
    c: CHAR;
175
    c: CHAR;
168
    hex: BOOLEAN;
176
    hex: BOOLEAN;
Line 169... Line 177...
169
    error: INTEGER;
177
    error, sym: INTEGER;
170
 
178
 
171
BEGIN
179
BEGIN
Line 172... Line 180...
172
    c := text.peak;
180
    c := text.peak;
Line 173... Line 181...
173
    ASSERT(S.digit(c));
181
    ASSERT(S.digit(c));
174
 
182
 
Line 175... Line 183...
175
    error := 0;
183
    error := 0;
176
 
184
 
177
    lex.sym := lxINTEGER;
185
    sym := lxINTEGER;
Line 189... Line 197...
189
    END;
197
    END;
Line 190... Line 198...
190
 
198
 
191
    IF c = "H" THEN
199
    IF c = "H" THEN
192
        putchar(lex, c);
200
        putchar(lex, c);
193
        TXT.next(text);
201
        TXT.next(text);
Line 194... Line 202...
194
        lex.sym := lxHEX
202
        sym := lxHEX
195
 
203
 
196
    ELSIF c = "X" THEN
204
    ELSIF c = "X" THEN
197
        putchar(lex, c);
205
        putchar(lex, c);
Line 198... Line 206...
198
        TXT.next(text);
206
        TXT.next(text);
Line 199... Line 207...
199
        lex.sym := lxCHAR
207
        sym := lxCHAR
200
 
208
 
201
    ELSIF c = "." THEN
209
    ELSIF c = "." THEN
Line 202... Line 210...
202
 
210
 
Line 203... Line 211...
203
        IF hex THEN
211
        IF hex THEN
204
            lex.sym := lxERROR01
212
            sym := lxERROR01
205
        ELSE
213
        ELSE
206
 
214
 
207
            c := nextc(text);
215
            c := nextc(text);
208
 
216
 
209
            IF c # "." THEN
217
            IF c # "." THEN
210
                putchar(lex, ".");
218
                putchar(lex, ".");
Line 211... Line 219...
211
                lex.sym := lxFLOAT
219
                sym := lxFLOAT
Line 233... Line 241...
233
                    WHILE S.digit(c) DO
241
                    WHILE S.digit(c) DO
234
                        putchar(lex, c);
242
                        putchar(lex, c);
235
                        c := nextc(text)
243
                        c := nextc(text)
236
                    END
244
                    END
237
                ELSE
245
                ELSE
238
                    lex.sym := lxERROR02
246
                    sym := lxERROR02
239
                END
247
                END
Line 240... Line 248...
240
 
248
 
Line 241... Line 249...
241
            END
249
            END
Line 242... Line 250...
242
 
250
 
243
        END
251
        END
Line 244... Line 252...
244
 
252
 
Line 245... Line 253...
245
    ELSIF hex THEN
253
    ELSIF hex THEN
246
        lex.sym := lxERROR01
254
        sym := lxERROR01
247
 
255
 
Line 248... Line 256...
248
    END;
256
    END;
249
 
257
 
250
    IF lex.over & (lex.sym >= 0) THEN
258
    IF lex.over & (sym >= 0) THEN
251
        lex.sym := lxERROR07
259
        sym := lxERROR07
252
    END;
260
    END;
253
 
261
 
254
    IF lex.sym = lxINTEGER THEN
262
    IF sym = lxINTEGER THEN
Line 255... Line 263...
255
        ARITH.iconv(lex.s, lex.value, error)
263
        ARITH.iconv(lex.s, lex.value, error)
256
    ELSIF (lex.sym = lxHEX) OR (lex.sym = lxCHAR) THEN
264
    ELSIF (sym = lxHEX) OR (sym = lxCHAR) THEN
257
        ARITH.hconv(lex.s, lex.value, error)
265
        ARITH.hconv(lex.s, lex.value, error)
258
    ELSIF lex.sym = lxFLOAT THEN
266
    ELSIF sym = lxFLOAT THEN
259
        ARITH.fconv(lex.s, lex.value, error)
267
        ARITH.fconv(lex.s, lex.value, error)
260
    END;
268
    END;
261
 
269
 
262
    CASE error OF
270
    CASE error OF
Line -... Line 271...
-
 
271
    |0:
263
    |0:
272
    |1: sym := lxERROR08
Line 264... Line 273...
264
    |1: lex.sym := lxERROR08
273
    |2: sym := lxERROR09
265
    |2: lex.sym := lxERROR09
274
    |3: sym := lxERROR10
Line 347... Line 356...
347
 
356
 
Line 348... Line 357...
348
END comment;
357
END comment;
-
 
358
 
-
 
359
 
-
 
360
PROCEDURE delimiter (text: TXT.TEXT; VAR lex: LEX; c: CHAR);
349
 
361
VAR
350
 
362
    sym: INTEGER;
351
PROCEDURE delimiter (text: TXT.TEXT; VAR lex: LEX; c: CHAR);
363
 
Line 352... Line 364...
352
BEGIN
364
BEGIN
353
    putchar(lex, c);
365
    putchar(lex, c);
354
    c := nextc(text);
366
    c := nextc(text);
Line 355... Line 367...
355
 
367
 
356
    CASE lex.s[0] OF
368
    CASE lex.s[0] OF
Line 357... Line 369...
357
    |"+":
369
    |"+":
358
        lex.sym := lxPLUS
370
        sym := lxPLUS
Line 359... Line 371...
359
 
371
 
360
    |"-":
372
    |"-":
Line 361... Line 373...
361
        lex.sym := lxMINUS
373
        sym := lxMINUS
362
 
374
 
363
    |"*":
375
    |"*":
364
        lex.sym := lxMUL
376
        sym := lxMUL
365
 
377
 
366
    |"/":
378
    |"/":
Line 367... Line 379...
367
        lex.sym := lxSLASH;
379
        sym := lxSLASH;
368
 
380
 
Line 369... Line 381...
369
        IF c = "/" THEN
381
        IF c = "/" THEN
370
            lex.sym := lxCOMMENT;
382
            sym := lxCOMMENT;
Line 371... Line 383...
371
            REPEAT
383
            REPEAT
372
                TXT.next(text)
384
                TXT.next(text)
Line 373... Line 385...
373
            UNTIL text.eol OR text.eof
385
            UNTIL text.eol OR text.eof
374
        END
386
        END
375
 
387
 
376
    |"~":
388
    |"~":
377
        lex.sym := lxNOT
389
        sym := lxNOT
Line 378... Line 390...
378
 
390
 
379
    |"&":
391
    |"&":
Line 380... Line 392...
380
        lex.sym := lxAND
392
        sym := lxAND
381
 
393
 
Line 382... Line 394...
382
    |".":
394
    |".":
383
        lex.sym := lxPOINT;
395
        sym := lxPOINT;
Line 384... Line 396...
384
 
396
 
385
        IF c = "." THEN
397
        IF c = "." THEN
Line 386... Line 398...
386
            lex.sym := lxRANGE;
398
            sym := lxRANGE;
387
            putchar(lex, c);
399
            putchar(lex, c);
388
            TXT.next(text)
400
            TXT.next(text)
389
        END
401
        END
390
 
402
 
Line 391... Line 403...
391
    |",":
403
    |",":
392
        lex.sym := lxCOMMA
404
        sym := lxCOMMA
Line 393... Line 405...
393
 
405
 
394
    |";":
406
    |";":
Line 395... Line 407...
395
        lex.sym := lxSEMI
407
        sym := lxSEMI
396
 
408
 
Line 397... Line 409...
397
    |"|":
409
    |"|":
398
        lex.sym := lxBAR
410
        sym := lxBAR
Line 399... Line 411...
399
 
411
 
400
    |"(":
412
    |"(":
Line 401... Line 413...
401
        lex.sym := lxLROUND;
413
        sym := lxLROUND;
402
 
414
 
Line 403... Line 415...
403
        IF c = "*" THEN
415
        IF c = "*" THEN
404
            lex.sym := lxCOMMENT;
416
            sym := lxCOMMENT;
405
            TXT.next(text);
417
            TXT.next(text);
406
            comment(text)
418
            comment(text)
407
        END
419
        END
Line 408... Line 420...
408
 
420
 
409
    |"[":
421
    |"[":
Line 410... Line 422...
410
        lex.sym := lxLSQUARE
422
        sym := lxLSQUARE
411
 
423
 
412
    |"{":
424
    |"{":
413
        lex.sym := lxLCURLY
425
        sym := lxLCURLY
414
 
426
 
Line 415... Line 427...
415
    |"^":
427
    |"^":
416
        lex.sym := lxCARET
428
        sym := lxCARET
Line 417... Line 429...
417
 
429
 
418
    |"=":
430
    |"=":
419
        lex.sym := lxEQ
431
        sym := lxEQ
420
 
432
 
421
    |"#":
433
    |"#":
Line 422... Line 434...
422
        lex.sym := lxNE
434
        sym := lxNE
423
 
435
 
Line 424... Line 436...
424
    |"<":
436
    |"<":
425
        lex.sym := lxLT;
437
        sym := lxLT;
Line 426... Line 438...
426
 
438
 
427
        IF c = "=" THEN
439
        IF c = "=" THEN
Line 428... Line 440...
428
            lex.sym := lxLE;
440
            sym := lxLE;
-
 
441
            putchar(lex, c);
-
 
442
            TXT.next(text)
Line 429... Line 443...
429
            putchar(lex, c);
443
        END
Line 430... Line 444...
430
            TXT.next(text)
444
 
431
        END
445
    |">":
432
 
446
        sym := lxGT;
Line -... Line 447...
-
 
447
 
-
 
448
        IF c = "=" THEN
-
 
449
            sym := lxGE;
-
 
450
            putchar(lex, c);
-
 
451
            TXT.next(text)
-
 
452
        END
-
 
453
 
-
 
454
    |":":
-
 
455
        sym := lxCOLON;
-
 
456
 
-
 
457
        IF c = "=" THEN
-
 
458
            sym := lxASSIGN;
-
 
459
            putchar(lex, c);
-
 
460
            TXT.next(text)
-
 
461
        END
-
 
462
 
-
 
463
    |")":
-
 
464
        sym := lxRROUND
-
 
465
 
-
 
466
    |"]":
-
 
467
        sym := lxRSQUARE
-
 
468
 
-
 
469
    |"}":
-
 
470
        sym := lxRCURLY
-
 
471
 
-
 
472
    END;
-
 
473
 
-
 
474
    lex.sym := sym
-
 
475
 
-
 
476
END delimiter;
-
 
477
 
-
 
478
 
-
 
479
PROCEDURE Next* (text: SCANNER; VAR lex: LEX);
-
 
480
VAR
-
 
481
    c: CHAR;
-
 
482
 
-
 
483
 
-
 
484
    PROCEDURE check (cond: BOOLEAN; text: SCANNER; lex: LEX; errno: INTEGER);
-
 
485
    BEGIN
-
 
486
        IF ~cond THEN
-
 
487
            ERRORS.ErrorMsg(text.fname, lex.pos.line, lex.pos.col, errno)
-
 
488
        END
-
 
489
    END check;
-
 
490
 
-
 
491
 
-
 
492
    PROCEDURE IsDef (str: ARRAY OF CHAR): BOOLEAN;
-
 
493
    VAR
-
 
494
        cur: DEF;
-
 
495
 
-
 
496
    BEGIN
-
 
497
        cur := def.first(DEF);
-
 
498
        WHILE (cur # NIL) & (cur.ident # str) DO
-
 
499
            cur := cur.next(DEF)
-
 
500
        END
-
 
501
 
-
 
502
        RETURN cur # NIL
-
 
503
    END IsDef;
-
 
504
 
-
 
505
 
-
 
506
    PROCEDURE Skip (text: SCANNER);
-
 
507
    VAR
-
 
508
        i: INTEGER;
-
 
509
 
-
 
510
    BEGIN
-
 
511
        i := 0;
-
 
512
        WHILE (i <= text.ifc) & ~text._skip[i] DO
-
 
513
            INC(i)
-
 
514
        END;
-
 
515
        text.skip := i <= text.ifc
-
 
516
    END Skip;
-
 
517
 
-
 
518
 
-
 
519
    PROCEDURE prep_if (text: SCANNER; VAR lex: LEX);
-
 
520
    VAR
-
 
521
        skip: BOOLEAN;
-
 
522
 
-
 
523
    BEGIN
-
 
524
        INC(text.ifc);
-
 
525
        text._elsif[text.ifc] := lex.sym = lxELSIF;
-
 
526
        IF lex.sym = lxIF THEN
-
 
527
            INC(text.elsec);
-
 
528
            text._else[text.elsec] := FALSE
-
 
529
        END;
-
 
530
        _if := TRUE;
-
 
531
        skip := TRUE;
-
 
532
        text.skip := FALSE;
-
 
533
 
-
 
534
        Next(text, lex);
-
 
535
        check(lex.sym = lxLROUND, text, lex, 64);
-
 
536
 
-
 
537
        Next(text, lex);
-
 
538
        check(lex.sym = lxIDENT, text, lex, 22);
-
 
539
 
-
 
540
        REPEAT
-
 
541
            IF IsDef(lex.s) THEN
-
 
542
                skip := FALSE
-
 
543
            END;
-
 
544
 
-
 
545
            Next(text, lex);
-
 
546
            IF lex.sym = lxBAR THEN
-
 
547
                Next(text, lex);
433
    |">":
548
                check(lex.sym = lxIDENT, text, lex, 22)
Line 434... Line 549...
434
        lex.sym := lxGT;
549
            ELSE
435
 
550
                check(lex.sym = lxRROUND, text, lex, 33)
Line 488... Line 603...
488
            number(text, lex)
603
            number(text, lex)
489
        ELSIF (c = '"') OR (c = "'") THEN
604
        ELSIF (c = '"') OR (c = "'") THEN
490
            string(text, lex, c)
605
            string(text, lex, c)
491
        ELSIF delimiters[ORD(c)] THEN
606
        ELSIF delimiters[ORD(c)] THEN
492
            delimiter(text, lex, c)
607
            delimiter(text, lex, c)
-
 
608
        ELSIF c = "$" THEN
-
 
609
            IF S.letter(nextc(text)) THEN
-
 
610
                ident(text, lex);
-
 
611
                IF lex.sym = lxIF THEN
-
 
612
                    IF ~_if THEN
-
 
613
                        prep_if(text, lex)
-
 
614
                    END
-
 
615
                ELSIF (lex.sym = lxEND) OR (lex.sym = lxELSE) OR (lex.sym = lxELSIF) THEN
-
 
616
                    IF ~_if THEN
-
 
617
                        prep_end(text, lex)
-
 
618
                    END
-
 
619
                ELSE
-
 
620
                    check(FALSE, text, lex, 119)
-
 
621
                END
-
 
622
            ELSE
-
 
623
                check(FALSE, text, lex, 119)
-
 
624
            END
493
        ELSIF c = 0X THEN
625
        ELSIF c = 0X THEN
494
            lex.sym := lxEOF;
626
            lex.sym := lxEOF;
-
 
627
            text.skip := FALSE;
495
            IF text.eof THEN
628
            IF text.eof THEN
496
                INC(lex.pos.col)
629
                INC(lex.pos.col)
497
            END
630
            END
498
        ELSIF (c = 7FX) & upto THEN
631
        ELSIF (c = 7FX) & upto THEN
499
            upto := FALSE;
632
            upto := FALSE;
Line 512... Line 645...
512
            lex.error := -lex.sym
645
            lex.error := -lex.sym
513
        ELSE
646
        ELSE
514
            lex.error := 0
647
            lex.error := 0
515
        END
648
        END
Line 516... Line 649...
516
 
649
 
Line 517... Line 650...
517
    UNTIL lex.sym # lxCOMMENT
650
    UNTIL (lex.sym # lxCOMMENT) & ~text.skip
Line 518... Line 651...
518
 
651
 
Line 528... Line 661...
528
BEGIN
661
BEGIN
529
    TXT.close(scanner)
662
    TXT.close(scanner)
530
END close;
663
END close;
Line 531... Line 664...
531
 
664
 
532
 
665
 
533
PROCEDURE init;
666
PROCEDURE init* (lower: BOOLEAN);
534
VAR
667
VAR
Line 535... Line 668...
535
    i: INTEGER;
668
    i: INTEGER;
536
    delim: ARRAY 23 OF CHAR;
669
    delim: ARRAY 23 OF CHAR;
537
 
670
 
-
 
671
 
Line 538... Line 672...
538
 
672
    PROCEDURE enterkw (key: INTEGER; kw: LEXSTR);
-
 
673
    VAR
539
    PROCEDURE enterkw (key: INTEGER; kw: LEXSTR);
674
        id: IDENT;
540
    VAR
675
        upper: LEXSTR;
-
 
676
 
-
 
677
    BEGIN
-
 
678
        IF LowerCase THEN
-
 
679
            id := enterid(kw);
-
 
680
            id.key := key
541
        id: IDENT;
681
        END;
Line 542... Line 682...
542
 
682
        upper := kw;
543
    BEGIN
683
        S.UpCase(upper);
-
 
684
        id := enterid(upper);
Line 544... Line 685...
544
        id := enterid(kw);
685
        id.key := key
545
        id.key := key
686
    END enterkw;
546
    END enterkw;
687
 
Line 565... Line 706...
565
    NewIdent.offsetW := -1;
706
    NewIdent.offsetW := -1;
566
    NewIdent.key     := 0;
707
    NewIdent.key     := 0;
Line 567... Line 708...
567
 
708
 
Line 568... Line 709...
568
    idents := NIL;
709
    idents := NIL;
569
 
710
 
570
    enterkw(lxARRAY, "ARRAY");
711
    enterkw(lxARRAY, "array");
571
    enterkw(lxBEGIN, "BEGIN");
712
    enterkw(lxBEGIN, "begin");
572
    enterkw(lxBY, "BY");
713
    enterkw(lxBY, "by");
573
    enterkw(lxCASE, "CASE");
714
    enterkw(lxCASE, "case");
574
    enterkw(lxCONST, "CONST");
715
    enterkw(lxCONST, "const");
575
    enterkw(lxDIV, "DIV");
716
    enterkw(lxDIV, "div");
576
    enterkw(lxDO, "DO");
717
    enterkw(lxDO, "do");
577
    enterkw(lxELSE, "ELSE");
718
    enterkw(lxELSE, "else");
578
    enterkw(lxELSIF, "ELSIF");
719
    enterkw(lxELSIF, "elsif");
579
    enterkw(lxEND, "END");
720
    enterkw(lxEND, "end");
580
    enterkw(lxFALSE, "FALSE");
721
    enterkw(lxFALSE, "false");
581
    enterkw(lxFOR, "FOR");
722
    enterkw(lxFOR, "for");
582
    enterkw(lxIF, "IF");
723
    enterkw(lxIF, "if");
583
    enterkw(lxIMPORT, "IMPORT");
724
    enterkw(lxIMPORT, "import");
584
    enterkw(lxIN, "IN");
725
    enterkw(lxIN, "in");
585
    enterkw(lxIS, "IS");
726
    enterkw(lxIS, "is");
586
    enterkw(lxMOD, "MOD");
727
    enterkw(lxMOD, "mod");
587
    enterkw(lxMODULE, "MODULE");
728
    enterkw(lxMODULE, "module");
588
    enterkw(lxNIL, "NIL");
729
    enterkw(lxNIL, "nil");
589
    enterkw(lxOF, "OF");
730
    enterkw(lxOF, "of");
590
    enterkw(lxOR, "OR");
731
    enterkw(lxOR, "or");
591
    enterkw(lxPOINTER, "POINTER");
732
    enterkw(lxPOINTER, "pointer");
592
    enterkw(lxPROCEDURE, "PROCEDURE");
733
    enterkw(lxPROCEDURE, "procedure");
593
    enterkw(lxRECORD, "RECORD");
734
    enterkw(lxRECORD, "record");
594
    enterkw(lxREPEAT, "REPEAT");
735
    enterkw(lxREPEAT, "repeat");
595
    enterkw(lxRETURN, "RETURN");
736
    enterkw(lxRETURN, "return");
596
    enterkw(lxTHEN, "THEN");
737
    enterkw(lxTHEN, "then");
597
    enterkw(lxTO, "TO");
738
    enterkw(lxTO, "to");
598
    enterkw(lxTRUE, "TRUE");
739
    enterkw(lxTRUE, "true");
599
    enterkw(lxTYPE, "TYPE");
740
    enterkw(lxTYPE, "type");
600
    enterkw(lxUNTIL, "UNTIL");
741
    enterkw(lxUNTIL, "until");
Line 601... Line 742...
601
    enterkw(lxVAR, "VAR");
742
    enterkw(lxVAR, "var");
Line -... Line 743...
-
 
743
    enterkw(lxWHILE, "while")
-
 
744
 
-
 
745
END init;
-
 
746
 
-
 
747
 
-
 
748
PROCEDURE NewDef* (str: ARRAY OF CHAR);
-
 
749
VAR
-
 
750
    item: DEF;
-
 
751
 
-
 
752
BEGIN
-
 
753
    NEW(item);
602
    enterkw(lxWHILE, "WHILE")
754
    COPY(str, item.ident);
603
 
755
    LISTS.push(def, item)
604
END init;
756
END NewDef;
605
 
757