;; Loading file /home/pjb/.clisprc.lisp ... ;; Reading ASDF packages from /home/pjb/asdf-central-registry.data... ; loading system definition from /usr/local/share/lisp/packages/net/sourceforge/cclan/asdf-install/asdf-install.asd into # ; registering # as ASDF-INSTALL 0 errors, 0 warnings [1]> (setf *print-circle* nil) NIL ;;; First we load the parser generator. [2]> (load"rdp.lisp") ;; Loading file rdp.lisp ... ;; Loaded file rdp.lisp T ;;; Second we load the pseudo basic generator. [5]> (load"rdp-basic-gen.lisp") ;; Loading file rdp-basic-gen.lisp ... WARNING: The generic function # is being modified, but has already been called. ;; Loaded file rdp-basic-gen.lisp T ;;; Next, we load the grammar definition. ;;; This will generate the scanner and parser for that language. ;;; We could write: (with-open-file (*standard-output* "parser.bas" ;;; :direction :output :if-exists :supersede ;;; :if-does-not-exist :create) ;;; (load "example-basic.lisp")) ;;; to save the basic program into the file "parser.bas". [6]> (load"example-basic.lisp") ;; Loading file example-basic.lisp ... 10 SCANSRC$="" : SCANFUN$="" : SCANPOS=0 20 CURTOK$="" : CURTXT$="" : CURPOS=0 30 SPACES$= 40 DEF SCANEOF : IF LEN(SCANSRC$)<=SCANPOS THEN RETURN 1 ELSE RETURN 0 : ENDFUN 50 SUB ACCEPT 60 IF TOKEN$ <> CURTOK$ THEN 70 PRINT "ERROR: AT POSITION",CURPOS,"EXPECTED ",TOKEN$," NOT ",CURTOK$ 80 STOP 90 ELSE 100 ACCEPTOK$=CURTOK$:ACCEPTXT$=CURTXT$:ACCEPPOS$=CURPOS$ 110 CALL SCANFUN$ 120 ENDIF 130 ENDSUB 140 MAXCONS=100000 150 NIL=0:CONS=1:STRING=2:NUMBER=3 160 TYPELABEL$[NIL]="NIL" 170 TYPELABEL$[CONS]="CONS" 180 TYPELABEL$[STRING]="STRING" 190 TYPELABEL$[NUMBER]="NUMBER" 200 DIM TYPES[MAXCONS],CAR[MAXCONS],CDR[MAXCONS],STRINGS$[MAXCONS],NUMBERS[MAXCONS] 210 TYPES[NIL]=NIL:CAR[NIL]=NIL:CDR[NIL]=NIL:STRINGS$[NIL]="NIL":NUMBERS[NIL]=0 220 FREE=MAXCONS 230 SUB CONS 240 IF FREE<=1 THEN PRINT "ERROR: OUT OF CONS SPACE" : STOP : ENDIF 250 FREE=FREE-1 260 TYPES[FREE]=CONS 270 CAR[FREE]=NCAR 280 CDR[FREE]=NCDR 290 RES=FREE 300 ENDSUB 310 SUB MKSTR 320 IF FREE<=1 THEN PRINT "ERROR: OUT OF CONS SPACE" : STOP : ENDIF 330 FREE=FREE-1 340 TYPES[FREE]=STRING 350 STRING$[FREE]=NSTRING$ 360 RES=FREE 370 ENDSUB 380 SUB MKNUM 390 IF FREE<=1 THEN PRINT "ERROR: OUT OF CONS SPACE" : STOP : ENDIF 400 FREE=FREE-1 410 TYPES[FREE]=NUMBER 420 NUMBER[FREE]=NNUMBER 430 RES=FREE 440 ENDSUB 450 SUB REVERSE 460 REV=0:TREV=NIL 470 WHILE LIST<>0 480 IF TYPES[LIST]<>CONS THEN 490 PRINT "ERROR: REVERSE EXPECTS A LIST, NOT A ",TYPELABEL$[TYPES[LIST]] 500 STOP 510 ELSE 520 NEW=CDR[LIST] 530 CDR[LIST]=REV:TYPES[LIST]=TREV 540 REV=LIST:TREV=CONS 550 LIST=NEW 560 ENDIF 570 ENDWHILE 580 RES=REV 590 ENDSUB 600 SUB SCANEXAMPLE 610 WHILE POS(SCANSRC$[SCANPOS],SPACES$)>0 : SCANPOS=SCANPOS+1 : ENDWHILE 620 CURPOS=SCANPOS 630 IF SCANEOF<>0 THEN 640 SCANPOS=LEN(SCANSRC$) 650 SCANTXT$="" 660 SCANTOK$="" 670 ELSE 680 REM ASSUMING THERE IS SOME WAY TO MATCH REGEXPS IN BASIC... 690 MATCHREGEXP "^\(procedure\>\|begin\>\|while\>\|const\>\|call\>\|then\>\|odd\>\|end\>\|var\>\|<=\|>=\|:=\|if\>\|do\>\|(\|)\|\*\|/\|+\|-\|#\|<\|>\|=\|,\|;\|\.\)" SCANSRC$,SCANPOS INTO START,END 700 IF START>0 THEN 710 SCANPOS=END 720 SCANTXT$=MID$(SCANSRC$,START,END) 730 SCANTOK$=SCANTXT$ 740 ELSE 750 MATCHREGEXP "^\\([A-Za-z][A-Za-z0-9]*\\)" SCANSRC$,SCANPOS INTO START,END 760 IF START>0 THEN 770 SCANPOS=END 780 SCANTXT$=MID$(SCANSRC$,START,END) 790 SCANTOK$="IDENT" 800 ELSE 810 MATCHREGEXP "^\\(^\([-+]\?[0-9]\+\.[0-9]\+\([Ee][-+]\?[0-9]\+\)\?\)\\)" SCANSRC$,SCANPOS INTO START,END 820 IF START>0 THEN 830 SCANPOS=END 840 SCANTXT$=MID$(SCANSRC$,START,END) 850 SCANTOK$="REAL" 860 ELSE 870 MATCHREGEXP "^\\([-+]\?[0-9]\+\\)" SCANSRC$,SCANPOS INTO START,END 880 IF START>0 THEN 890 SCANPOS=END 900 SCANTXT$=MID$(SCANSRC$,START,END) 910 SCANTOK$="INTEGER" 920 ELSE 930 PRINT "ERROR: AT POSITION",CURPOS,"EXPECTED ",TOKEN$," NOT ",CURTOK$ 940 STOP 950 ENDIF 960 ENDIF 970 ENDIF 980 ENDIF 990 ENDIF 1000 ENDSUB 1010 SUB PARSEPROGRAM 1020 IF (CURTOK$="IDENT" OR CURTOK$="call" OR CURTOK$="begin" OR CURTOK$="if" OR CURTOK$="while" OR CURTOK$="procedure" OR CURTOK$="var" OR CURTOK$="const") THEN 1030 CALL PARSEBLOCK 1040 ELSE 1050 RET=NIL 1060 ENDIF 1070 L1A1=RES 1080 TOKEN$="." : CALL ACCEPT 1090 L1A2=RES 1100 A2=L1A2:NCAR=A2:NCDR=NIL:CALL CONS:A0=RES 1110 A1=L1A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 1120 RES=A1 1130 ENDSUB 1140 SUB PARSEFACTOR 1150 IF (CURTOK$="IDENT") THEN 1160 TOKEN$="IDENT" : CALL ACCEPT 1170 ELSE 1180 IF (CURTOK$="INTEGER" OR CURTOK$="REAL") THEN 1190 IF (CURTOK$="INTEGER" OR CURTOK$="REAL") THEN 1200 CALL PARSENUMBER 1210 ELSE 1220 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 1230 STOP 1240 ENDIF 1250 ELSE 1260 IF (CURTOK$="(") THEN 1270 TOKEN$="(" : CALL ACCEPT 1280 L3A1=RES 1290 IF (CURTOK$="IDENT" OR CURTOK$="INTEGER" OR CURTOK$="REAL" OR CURTOK$="(" OR CURTOK$="+" OR CURTOK$="-") THEN 1300 CALL PARSEEXPRESSION 1310 ELSE 1320 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 1330 STOP 1340 ENDIF 1350 L3A2=RES 1360 TOKEN$=")" : CALL ACCEPT 1370 L3A3=RES 1380 A3=L3A3:NCAR=A3:NCDR=NIL:CALL CONS:A0=RES 1390 A2=L3A2:NCAR=A2:NCDR=A0:CALL CONS:A0=RES 1400 A1=L3A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 1410 RES=A2 1420 ELSE 1430 PRINT "ERROR: DID NOT EXPECT ",CURTOK$ 1440 STOP 1450 ENDIF 1460 ENDIF 1470 ENDIF 1480 L2A1=RES 1490 A1=L2A1:NCAR=A1:NCDR=NIL:CALL CONS:A0=RES 1500 RES=A1 1510 ENDSUB 1520 SUB PARSETERM 1530 IF (CURTOK$="IDENT" OR CURTOK$="INTEGER" OR CURTOK$="REAL" OR CURTOK$="(") THEN 1540 CALL PARSEFACTOR 1550 ELSE 1560 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 1570 STOP 1580 ENDIF 1590 L4A1=RES 1600 L5RES=NIL 1610 WHILE (CURTOK$="*" OR CURTOK$="/") 1620 IF (CURTOK$="*") THEN 1630 TOKEN$="*" : CALL ACCEPT 1640 ELSE 1650 IF (CURTOK$="/") THEN 1660 TOKEN$="/" : CALL ACCEPT 1670 ELSE 1680 PRINT "ERROR: DID NOT EXPECT ",CURTOK$ 1690 STOP 1700 ENDIF 1710 ENDIF 1720 L6A1=RES 1730 IF (CURTOK$="IDENT" OR CURTOK$="INTEGER" OR CURTOK$="REAL" OR CURTOK$="(") THEN 1740 CALL PARSEFACTOR 1750 ELSE 1760 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 1770 STOP 1780 ENDIF 1790 L6A2=RES 1800 A2=L6A2:NCAR=A2:NCDR=NIL:CALL CONS:A0=RES 1810 A1=L6A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 1820 $0 1830 NCAR=RET:NCDR=L5RES:CALL CONS:L5RES=RES 1840 ENDWHILE 1850 LIST=L5RES:CALL REVERSE 1860 L4A2=RES 1870 A2=L4A2:NCAR=A2:NCDR=NIL:CALL CONS:A0=RES 1880 A1=L4A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 1890 NCAR=A1:NCDR=A2:CALL CONS 1900 ENDSUB 1910 SUB PARSEEXPRESSION 1920 L8RES=NIL 1930 IF (CURTOK$="+" OR CURTOK$="-") THEN 1940 IF (CURTOK$="+") THEN 1950 TOKEN$="+" : CALL ACCEPT 1960 ELSE 1970 IF (CURTOK$="-") THEN 1980 TOKEN$="-" : CALL ACCEPT 1990 ELSE 2000 PRINT "ERROR: DID NOT EXPECT ",CURTOK$ 2010 STOP 2020 ENDIF 2030 ENDIF 2040 ELSE 2050 RES=NIL 2060 ENDIF 2070 L7A1=RES 2080 IF (CURTOK$="IDENT" OR CURTOK$="INTEGER" OR CURTOK$="REAL" OR CURTOK$="(") THEN 2090 CALL PARSETERM 2100 ELSE 2110 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 2120 STOP 2130 ENDIF 2140 L7A2=RES 2150 L9RES=NIL 2160 WHILE (CURTOK$="+" OR CURTOK$="-") 2170 IF (CURTOK$="+") THEN 2180 TOKEN$="+" : CALL ACCEPT 2190 ELSE 2200 IF (CURTOK$="-") THEN 2210 TOKEN$="-" : CALL ACCEPT 2220 ELSE 2230 PRINT "ERROR: DID NOT EXPECT ",CURTOK$ 2240 STOP 2250 ENDIF 2260 ENDIF 2270 L10A1=RES 2280 IF (CURTOK$="IDENT" OR CURTOK$="INTEGER" OR CURTOK$="REAL" OR CURTOK$="(") THEN 2290 CALL PARSETERM 2300 ELSE 2310 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 2320 STOP 2330 ENDIF 2340 L10A2=RES 2350 A2=L10A2:NCAR=A2:NCDR=NIL:CALL CONS:A0=RES 2360 A1=L10A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 2370 NCAR=A2:NCDR=NIL:CALL CONS 2380 NCAR=A1:NCDR=RES:CALL CONS 2390 NCAR=RET:NCDR=L9RES:CALL CONS:L9RES=RES 2400 ENDWHILE 2410 LIST=L9RES:CALL REVERSE 2420 L7A3=RES 2430 A3=L7A3:NCAR=A3:NCDR=NIL:CALL CONS:A0=RES 2440 A2=L7A2:NCAR=A2:NCDR=A0:CALL CONS:A0=RES 2450 A1=L7A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 2460 IF A1<>0 THEN 2470 NCAR=A2:NCDR=NIL:CALL CONS 2480 NCAR=A1:NCDR=RES:CALL CONS 2490 NCAR=RES 2500 ELSE 2510 NCAR=A2 2520 ENDIF 2530 NCDR=A3:CALL CONS 2540 TMP=RES 2550 NSTRING$="+":CALL MKSTR:NCAR=RES:NCDR=TMP:CALL CONS 2560 ENDSUB 2570 SUB PARSECONDITION 2580 IF (CURTOK$="odd") THEN 2590 TOKEN$="odd" : CALL ACCEPT 2600 L12A1=RES 2610 IF (CURTOK$="IDENT" OR CURTOK$="INTEGER" OR CURTOK$="REAL" OR CURTOK$="(" OR CURTOK$="+" OR CURTOK$="-") THEN 2620 CALL PARSEEXPRESSION 2630 ELSE 2640 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 2650 STOP 2660 ENDIF 2670 L12A2=RES 2680 A2=L12A2:NCAR=A2:NCDR=NIL:CALL CONS:A0=RES 2690 A1=L12A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 2700 NCAR=A2:NCDR=NIL:CALL CONS:TMP=RES 2710 NSTRING$="ODD":CALL MKSTR 2720 NCAR=RES:NCDR=TMP:CALL CONS 2730 ELSE 2740 IF (CURTOK$="IDENT" OR CURTOK$="INTEGER" OR CURTOK$="REAL" OR CURTOK$="(" OR CURTOK$="+" OR CURTOK$="-") THEN 2750 IF (CURTOK$="IDENT" OR CURTOK$="INTEGER" OR CURTOK$="REAL" OR CURTOK$="(" OR CURTOK$="+" OR CURTOK$="-") THEN 2760 CALL PARSEEXPRESSION 2770 ELSE 2780 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 2790 STOP 2800 ENDIF 2810 L13A1=RES 2820 IF (CURTOK$="=") THEN 2830 TOKEN$="=" : CALL ACCEPT 2840 ELSE 2850 IF (CURTOK$="#") THEN 2860 TOKEN$="#" : CALL ACCEPT 2870 ELSE 2880 IF (CURTOK$="<") THEN 2890 TOKEN$="<" : CALL ACCEPT 2900 ELSE 2910 IF (CURTOK$="<=") THEN 2920 TOKEN$="<=" : CALL ACCEPT 2930 ELSE 2940 IF (CURTOK$=">") THEN 2950 TOKEN$=">" : CALL ACCEPT 2960 ELSE 2970 IF (CURTOK$=">=") THEN 2980 TOKEN$=">=" : CALL ACCEPT 2990 ELSE 3000 PRINT "ERROR: DID NOT EXPECT ",CURTOK$ 3010 STOP 3020 ENDIF 3030 ENDIF 3040 ENDIF 3050 ENDIF 3060 ENDIF 3070 ENDIF 3080 L13A2=RES 3090 IF (CURTOK$="IDENT" OR CURTOK$="INTEGER" OR CURTOK$="REAL" OR CURTOK$="(" OR CURTOK$="+" OR CURTOK$="-") THEN 3100 CALL PARSEEXPRESSION 3110 ELSE 3120 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 3130 STOP 3140 ENDIF 3150 L13A3=RES 3160 A3=L13A3:NCAR=A3:NCDR=NIL:CALL CONS:A0=RES 3170 A2=L13A2:NCAR=A2:NCDR=A0:CALL CONS:A0=RES 3180 A1=L13A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 3190 NCAR=A3:NCDR=NIL:CALL CONS 3200 NCAR=A1:NCDR=RES:CALL CONS 3210 NCAR=A2:NCDR=RES:CALL CONS 3220 ELSE 3230 PRINT "ERROR: DID NOT EXPECT ",CURTOK$ 3240 STOP 3250 ENDIF 3260 ENDIF 3270 L11A1=RES 3280 A1=L11A1:NCAR=A1:NCDR=NIL:CALL CONS:A0=RES 3290 RES=A1 3300 ENDSUB 3310 SUB PARSENUMBER 3320 IF (CURTOK$="INTEGER") THEN 3330 TOKEN$="INTEGER" : CALL ACCEPT 3340 ELSE 3350 IF (CURTOK$="REAL") THEN 3360 TOKEN$="REAL" : CALL ACCEPT 3370 ELSE 3380 PRINT "ERROR: DID NOT EXPECT ",CURTOK$ 3390 STOP 3400 ENDIF 3410 ENDIF 3420 L14A1=RES 3430 A1=L14A1:NCAR=A1:NCDR=NIL:CALL CONS:A0=RES 3440 RES=A1 3450 ENDSUB 3460 SUB PARSESTATEMENT 3470 L16RES=NIL 3480 IF (CURTOK$="IDENT" OR CURTOK$="call" OR CURTOK$="begin" OR CURTOK$="if" OR CURTOK$="while") THEN 3490 IF (CURTOK$="IDENT") THEN 3500 TOKEN$="IDENT" : CALL ACCEPT 3510 L17A1=RES 3520 TOKEN$=":=" : CALL ACCEPT 3530 L17A2=RES 3540 IF (CURTOK$="IDENT" OR CURTOK$="INTEGER" OR CURTOK$="REAL" OR CURTOK$="(" OR CURTOK$="+" OR CURTOK$="-") THEN 3550 CALL PARSEEXPRESSION 3560 ELSE 3570 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 3580 STOP 3590 ENDIF 3600 L17A3=RES 3610 A3=L17A3:NCAR=A3:NCDR=NIL:CALL CONS:A0=RES 3620 A2=L17A2:NCAR=A2:NCDR=A0:CALL CONS:A0=RES 3630 A1=L17A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 3640 NCAR=A3:NCDR=NIL:CALL CONS 3650 NCAR=A1:NCDR=RES:CALL CONS 3660 TMP=RES:NSTRING$="LET":CALL MKSTR 3670 NCAR=RES:NCDR=TMP:CALL CONS 3680 ELSE 3690 IF (CURTOK$="call") THEN 3700 TOKEN$="call" : CALL ACCEPT 3710 L18A1=RES 3720 TOKEN$="IDENT" : CALL ACCEPT 3730 L18A2=RES 3740 A2=L18A2:NCAR=A2:NCDR=NIL:CALL CONS:A0=RES 3750 A1=L18A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 3760 NCAR=A2:NCDR=NIL:CALL CONS 3770 TMP=RES:NSTRING$="CALL":CALL MKSTR 3780 NCAR=RES:NCDR=TMP:CALL CONS 3790 ELSE 3800 IF (CURTOK$="begin") THEN 3810 TOKEN$="begin" : CALL ACCEPT 3820 L19A1=RES 3830 IF (CURTOK$="IDENT" OR CURTOK$="call" OR CURTOK$="begin" OR CURTOK$="if" OR CURTOK$="while") THEN 3840 CALL PARSESTATEMENT 3850 ELSE 3860 RET=NIL 3870 ENDIF 3880 L19A2=RES 3890 L20RES=NIL 3900 WHILE (CURTOK$=";") 3910 TOKEN$=";" : CALL ACCEPT 3920 L21A1=RES 3930 IF (CURTOK$="IDENT" OR CURTOK$="call" OR CURTOK$="begin" OR CURTOK$="if" OR CURTOK$="while") THEN 3940 CALL PARSESTATEMENT 3950 ELSE 3960 RET=NIL 3970 ENDIF 3980 L21A2=RES 3990 A2=L21A2:NCAR=A2:NCDR=NIL:CALL CONS:A0=RES 4000 A1=L21A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 4010 RES=A2 4020 NCAR=RET:NCDR=L20RES:CALL CONS:L20RES=RES 4030 ENDWHILE 4040 LIST=L20RES:CALL REVERSE 4050 L19A3=RES 4060 TOKEN$="end" : CALL ACCEPT 4070 L19A4=RES 4080 A4=L19A4:NCAR=A4:NCDR=NIL:CALL CONS:A0=RES 4090 A3=L19A3:NCAR=A3:NCDR=A0:CALL CONS:A0=RES 4100 A2=L19A2:NCAR=A2:NCDR=A0:CALL CONS:A0=RES 4110 A1=L19A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 4120 NCAR=A2:NCDR=A3:CALL CONS 4130 ELSE 4140 IF (CURTOK$="if") THEN 4150 TOKEN$="if" : CALL ACCEPT 4160 L22A1=RES 4170 IF (CURTOK$="odd" OR CURTOK$="IDENT" OR CURTOK$="INTEGER" OR CURTOK$="REAL" OR CURTOK$="(" OR CURTOK$="+" OR CURTOK$="-") THEN 4180 CALL PARSECONDITION 4190 ELSE 4200 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 4210 STOP 4220 ENDIF 4230 L22A2=RES 4240 TOKEN$="then" : CALL ACCEPT 4250 L22A3=RES 4260 IF (CURTOK$="IDENT" OR CURTOK$="call" OR CURTOK$="begin" OR CURTOK$="if" OR CURTOK$="while") THEN 4270 CALL PARSESTATEMENT 4280 ELSE 4290 RET=NIL 4300 ENDIF 4310 L22A4=RES 4320 A4=L22A4:NCAR=A4:NCDR=NIL:CALL CONS:A0=RES 4330 A3=L22A3:NCAR=A3:NCDR=A0:CALL CONS:A0=RES 4340 A2=L22A2:NCAR=A2:NCDR=A0:CALL CONS:A0=RES 4350 A1=L22A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 4360 NCAR=A4:NCDR=NIL:CALL CONS 4370 NCAR=A2:NCDR=RES:CALL CONS 4380 TMP=RES:NSTRING$="IF":CALL MKSTR 4390 NCAR=RES:NCDR=TMP:CALL CONS 4400 ELSE 4410 IF (CURTOK$="while") THEN 4420 TOKEN$="while" : CALL ACCEPT 4430 L23A1=RES 4440 IF (CURTOK$="odd" OR CURTOK$="IDENT" OR CURTOK$="INTEGER" OR CURTOK$="REAL" OR CURTOK$="(" OR CURTOK$="+" OR CURTOK$="-") THEN 4450 CALL PARSECONDITION 4460 ELSE 4470 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 4480 STOP 4490 ENDIF 4500 L23A2=RES 4510 TOKEN$="do" : CALL ACCEPT 4520 L23A3=RES 4530 IF (CURTOK$="IDENT" OR CURTOK$="call" OR CURTOK$="begin" OR CURTOK$="if" OR CURTOK$="while") THEN 4540 CALL PARSESTATEMENT 4550 ELSE 4560 RET=NIL 4570 ENDIF 4580 L23A4=RES 4590 A4=L23A4:NCAR=A4:NCDR=NIL:CALL CONS:A0=RES 4600 A3=L23A3:NCAR=A3:NCDR=A0:CALL CONS:A0=RES 4610 A2=L23A2:NCAR=A2:NCDR=A0:CALL CONS:A0=RES 4620 A1=L23A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 4630 NCAR=A4:NCDR=NIL:CALL CONS 4640 NCAR=A2:NCDR=RES:CALL CONS 4650 TMP=RES:NSTRING$="WHILE":CALL MKSTR 4660 NCAR=RES:NCDR=TMP:CALL CONS 4670 ELSE 4680 PRINT "ERROR: DID NOT EXPECT ",CURTOK$ 4690 STOP 4700 ENDIF 4710 ENDIF 4720 ENDIF 4730 ENDIF 4740 ENDIF 4750 ELSE 4760 RES=NIL 4770 ENDIF 4780 L15A1=RES 4790 A1=L15A1:NCAR=A1:NCDR=NIL:CALL CONS:A0=RES 4800 RES=A1 4810 ENDSUB 4820 SUB PARSEBLOCK 4830 L25RES=NIL 4840 IF (CURTOK$="const") THEN 4850 TOKEN$="const" : CALL ACCEPT 4860 L26A1=RES 4870 TOKEN$="IDENT" : CALL ACCEPT 4880 L26A2=RES 4890 TOKEN$="=" : CALL ACCEPT 4900 L26A3=RES 4910 IF (CURTOK$="INTEGER" OR CURTOK$="REAL") THEN 4920 CALL PARSENUMBER 4930 ELSE 4940 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 4950 STOP 4960 ENDIF 4970 L26A4=RES 4980 L27RES=NIL 4990 WHILE (CURTOK$=",") 5000 TOKEN$="," : CALL ACCEPT 5010 L28A1=RES 5020 TOKEN$="IDENT" : CALL ACCEPT 5030 L28A2=RES 5040 TOKEN$="=" : CALL ACCEPT 5050 L28A3=RES 5060 IF (CURTOK$="INTEGER" OR CURTOK$="REAL") THEN 5070 CALL PARSENUMBER 5080 ELSE 5090 PRINT "ERROR: UNEXPECTED TOKEN ",SCANTOK$ 5100 STOP 5110 ENDIF 5120 L28A4=RES 5130 A4=L28A4:NCAR=A4:NCDR=NIL:CALL CONS:A0=RES 5140 A3=L28A3:NCAR=A3:NCDR=A0:CALL CONS:A0=RES 5150 A2=L28A2:NCAR=A2:NCDR=A0:CALL CONS:A0=RES 5160 A1=L28A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 5170 NCAR=A4:NCDR=NIL:CALL CONS 5180 NCAR=A2:NCDR=RES:CALL CONS 5190 NCAR=RET:NCDR=L27RES:CALL CONS:L27RES=RES 5200 ENDWHILE 5210 LIST=L27RES:CALL REVERSE 5220 L26A5=RES 5230 TOKEN$=";" : CALL ACCEPT 5240 L26A6=RES 5250 A6=L26A6:NCAR=A6:NCDR=NIL:CALL CONS:A0=RES 5260 A5=L26A5:NCAR=A5:NCDR=A0:CALL CONS:A0=RES 5270 A4=L26A4:NCAR=A4:NCDR=A0:CALL CONS:A0=RES 5280 A3=L26A3:NCAR=A3:NCDR=A0:CALL CONS:A0=RES 5290 A2=L26A2:NCAR=A2:NCDR=A0:CALL CONS:A0=RES 5300 A1=L26A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 5310 NCAR=A4:NCDR=NIL:CALL CONS 5320 NCAR=A2:NCDR=RES:CALL CONS 5330 NCAR=RES:NCDR=A5:CALL CONS 5340 ELSE 5350 RES=NIL 5360 ENDIF 5370 L24A1=RES 5380 L29RES=NIL 5390 IF (CURTOK$="var") THEN 5400 TOKEN$="var" : CALL ACCEPT 5410 L30A1=RES 5420 TOKEN$="IDENT" : CALL ACCEPT 5430 L30A2=RES 5440 L31RES=NIL 5450 WHILE (CURTOK$=",") 5460 TOKEN$="," : CALL ACCEPT 5470 L32A1=RES 5480 TOKEN$="IDENT" : CALL ACCEPT 5490 L32A2=RES 5500 A2=L32A2:NCAR=A2:NCDR=NIL:CALL CONS:A0=RES 5510 A1=L32A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 5520 RES=A2 5530 NCAR=RET:NCDR=L31RES:CALL CONS:L31RES=RES 5540 ENDWHILE 5550 LIST=L31RES:CALL REVERSE 5560 L30A3=RES 5570 TOKEN$=";" : CALL ACCEPT 5580 L30A4=RES 5590 A4=L30A4:NCAR=A4:NCDR=NIL:CALL CONS:A0=RES 5600 A3=L30A3:NCAR=A3:NCDR=A0:CALL CONS:A0=RES 5610 A2=L30A2:NCAR=A2:NCDR=A0:CALL CONS:A0=RES 5620 A1=L30A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 5630 NCAR=A3:NCDR=NIL:CALL CONS 5640 NCAR=A2:NCDR=RES:CALL CONS 5650 ELSE 5660 RES=NIL 5670 ENDIF 5680 L24A2=RES 5690 L33RES=NIL 5700 WHILE (CURTOK$="procedure") 5710 TOKEN$="procedure" : CALL ACCEPT 5720 L34A1=RES 5730 TOKEN$="IDENT" : CALL ACCEPT 5740 L34A2=RES 5750 TOKEN$=";" : CALL ACCEPT 5760 L34A3=RES 5770 IF (CURTOK$="IDENT" OR CURTOK$="call" OR CURTOK$="begin" OR CURTOK$="if" OR CURTOK$="while" OR CURTOK$="procedure" OR CURTOK$="var" OR CURTOK$="const") THEN 5780 CALL PARSEBLOCK 5790 ELSE 5800 RET=NIL 5810 ENDIF 5820 L34A4=RES 5830 TOKEN$=";" : CALL ACCEPT 5840 L34A5=RES 5850 A5=L34A5:NCAR=A5:NCDR=NIL:CALL CONS:A0=RES 5860 A4=L34A4:NCAR=A4:NCDR=A0:CALL CONS:A0=RES 5870 A3=L34A3:NCAR=A3:NCDR=A0:CALL CONS:A0=RES 5880 A2=L34A2:NCAR=A2:NCDR=A0:CALL CONS:A0=RES 5890 A1=L34A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 5900 NCAR=A4:NCDR=NIL:CALL CONS 5910 NCAR=A2:NCDR=RES:CALL CONS 5920 TMP=RES:NSTRING$="PROCEDURE":CALL MKSTR 5930 NCAR=RES:NCDR=TMP:CALL CONS 5940 NCAR=RET:NCDR=L33RES:CALL CONS:L33RES=RES 5950 ENDWHILE 5960 LIST=L33RES:CALL REVERSE 5970 L24A3=RES 5980 IF (CURTOK$="IDENT" OR CURTOK$="call" OR CURTOK$="begin" OR CURTOK$="if" OR CURTOK$="while") THEN 5990 CALL PARSESTATEMENT 6000 ELSE 6010 RET=NIL 6020 ENDIF 6030 L24A4=RES 6040 A4=L24A4:NCAR=A4:NCDR=NIL:CALL CONS:A0=RES 6050 A3=L24A3:NCAR=A3:NCDR=A0:CALL CONS:A0=RES 6060 A2=L24A2:NCAR=A2:NCDR=A0:CALL CONS:A0=RES 6070 A1=L24A1:NCAR=A1:NCDR=A0:CALL CONS:A0=RES 6080 NCAR=A4:NCDR=NIL:CALL CONS 6090 NCAR=A3:NCDR=RES:CALL CONS 6100 NCAR=A2:NCDR=RES:CALL CONS 6110 NCAR=A1:NCDR=RES:CALL CONS 6120 TMP=RES:NSTRING$="BLOCK":CALL MKSTR 6130 NCAR=RES:NCDR=TMP:CALL CONS 6140 ENDSUB 6150 SUB PARSEEXAMPLE 6160 SCANSRC$=SOURCE$ : SCANPOS=0 : SCANFUN$="SCANEXAMPLE" 6170 CALL SCANFUN$ 6180 CALL PARSEPROGRAM 6190 IF SCANEOF<>0 THEN 6200 PRINT "ERROR: END OF SOURCE NOT REACHED" 6210 STOP 6220 ENDIF 6230 ENDSUB ;; Loaded file example-basic.lisp T [7]> ;;; Parsing a source with this basic program would be done with: SOURCE$= " const abc = 123, pi=3.141592e+0; var a,b,c; procedure gcd; begin while a # b do begin if ab then a:=a-b end end; begin a:=42; b:=30.0; call gcd end." : CALL PARSEXAMPLE ;;; The resulting parse tree is stored in the CAR,CDR,TYPES,STRING$ and NUMBER ;;; arrays, the root of the tree being pointed to by RES.