[关闭]
@ydleenudt 2015-06-10T02:11:23.000000Z 字数 26647 阅读 1158

PL语言分析程序(in pascal)

增加部分

case语句

第一步:记录表达式的标记,处理表达式,标记常量的入口位置。
第二步:每次将表达式的值与常量进行比较,形成跳转指令,执行完一条语句之后产生无条件跳转指令。

  1. procedure casestatement; {case}
  2. var x:item;
  3. coni,conj:integer;
  4. begin
  5. getsym;cx1:=cx;
  6. expression([ofsym]+fsys,x);cx2:=cx;
  7. if (x.typ = ints) or (x.typ = chars)then
  8. begin
  9. if sym=ofsym then
  10. begin
  11. getsym;conj:=0;
  12. while sym<>elsesym do
  13. begin
  14. if (sym = intcon) or (sym = charcon) then
  15. begin
  16. coni:=cx1;
  17. if conj<>0 then
  18. begin
  19. while coni<cx2 do
  20. begin
  21. code[cx]:=code[coni];
  22. cx:=cx+
  23. coni:=coni+1;
  24. end
  25. end;
  26. conj:=1;
  27. gen(lit,0,num);
  28. coni:=cx1;
  29. end
  30. else error(12);
  31. getsym;
  32. if sym=colon then
  33. begin
  34. getsym;
  35. gen(eq,0,0);
  36. cx2:=cx;
  37. gen(jpc,0,0);
  38. statement([semicolon]+fsys);
  39. if sym=semicolon then
  40. begin
  41. getsym;
  42. labtab[lx]:=cx;lx:=lx+1;
  43. gen(jmp,0,0);
  44. code[cx2].a:=cx
  45. end
  46. else error(23)
  47. end
  48. else error(24){colon}
  49. end;
  50. if sym=elsesym then
  51. begin
  52. getsym;
  53. statement([endsym]+fsys);
  54. lx:=lx-1;
  55. while lx>=0 do
  56. begin code[labtab[lx]].a:=cx;
  57. lx:=lx-1
  58. end
  59. end;
  60. if sym=endsym then getsym
  61. else error(36)
  62. end
  63. else error(17)
  64. end
  65. end;
repeat语句

在第一条语句前记录标记,处理完语句之后,判断布尔表达式的值,并产生跳转指令。

  1. procedure repeatstatement;{repeat}
  2. var x:item;
  3. begin
  4. getsym;cx1:=cx; labtab[lx]:=cx;lx:=lx+1;
  5. statement([untilsym]+fsys);
  6. if sym<>semicolon then error(23);
  7. getsym;
  8. while (not (sym in ([untilsym]))) do
  9. begin
  10. statement([untilsym]+fsys);
  11. if sym<>semicolon then error(23);
  12. getsym
  13. end;
  14. if sym=untilsym then
  15. begin
  16. getsym;
  17. expression([endsym]+fsys,x);
  18. if x.typ <> bool then error(34);
  19. gen(jpc,0,cx1);labtab[lx]:=cx;lx:=lx+1
  20. end
  21. end;
for语句

第一步:通过词法扫描,先处理控制变量,将其装入符号表,读入初值之后存入控制变量对应的地址中。
第二步:读入终止值,每次判断是否满足条件,记录语句的标号,之后进入语句,处理完之后,将控制变量加一,并判断是否跳转。

  1. procedure forstatement;{for}
  2. begin
  3. getsym;
  4. if sym=ident then
  5. begin
  6. i:=position(id);getsym;
  7. if i=0 then error(10)
  8. else
  9. if nametab[i].kind<>variable then
  10. begin
  11. error(30);i:=0
  12. end
  13. else
  14. begin
  15. x.typ:=nametab[i].typ;
  16. x.ref:=nametab[i].ref;
  17. if nametab[i].normal
  18. then gen(loda,nametab[i].lev,nametab[i].adr)
  19. else gen(lod,nametab[i].lev,nametab[i].adr)
  20. end;
  21. if sym=becomes then
  22. begin
  23. getsym;
  24. expression([tosym]+fsys,ini);
  25. if ini.typ<>ints then error(12)
  26. else begin
  27. gen(sto,0,0);
  28. if sym=tosym then
  29. begin
  30. getsym;cx1:=cx;labtab[lx]:=cx;lx:=lx+1;
  31. gen(loda,nametab[i].lev,nametab[i].adr);
  32. gen(lodt,0,0);
  33. expression([dosym]+fsys,fin);
  34. if sym=dosym then
  35. begin
  36. gen(le,0,0);
  37. cx2:=cx;labtab[lx]:=cx;lx:=lx+1;
  38. gen(jpc,0,0);
  39. getsym;
  40. statement(fsys);
  41. if nametab[i].normal then
  42. begin
  43. gen(loda,nametab[i].lev,nametab[i].adr);
  44. gen(loda,nametab[i].lev,nametab[i].adr);
  45. gen(lodt,0,0)
  46. end
  47. else gen(lod,nametab[i].lev,nametab[i].adr);
  48. gen(lit,0,1);
  49. gen(add,0,0);
  50. gen(sto,0,0);
  51. gen(jmp,0,cx1);
  52. code[cx2].a:=cx
  53. end
  54. end
  55. end
  56. end
  57. end
  58. else error(33)
  59. end;

完整程序

  1. program plcopiler;
  2. uses dos;
  3. const norw=25; { no. of reserved words }
  4. txmax=100; { length of identifier table }
  5. bmax=25; { length of block inormation table }
  6. arrmax=30; { length of array information table }
  7. nmax=6; { max. no. of digits in numbers }
  8. al=10; { length of identifiers }
  9. amax=2047; { maxinum address }
  10. levmax=7; { maxinum depth of block nesting }
  11. cxmax=1000; { size of code array }
  12. type symbol=
  13. (nul,ident,intcon,charcon,plus,minus,times,divsym,
  14. eql,neq,lss,leq,gtr,geq, ofsym,arraysym,programsym,modsym,
  15. andsym,orsym,notsym,lbrack,rbrack,lparen,rparen,comma,
  16. semicolon,period,becomes,colon,beginsym,endsym,ifsym,casesym,thensym,
  17. elsesym,whilesym,repeatsym,dosym,callsym,constsym,typesym,
  18. varsym,procsym,forsym,untilsym,functionsym,tosym);
  19. alfa = string[al];
  20. index=-32767..+32767;
  21. oobject = (konstant,typel,variable,prosedure);
  22. types=(notyp,ints,chars,bool,arrays);
  23. symset = set of symbol;
  24. opcod = (lit,lod,ilod,loda,lodt,sto,lodb,cpyb,jmp,jpc,red,wrt,
  25. cal,retp,endp,udis,opac,entp,ands,ors,nots,imod,mus,add,
  26. sub,mult,idiv,eq,ne,ls,le,gt,ge); { opration code }
  27. instruction = packed record
  28. f:opcod;
  29. l:0..levmax;
  30. a:0..amax;
  31. end;
  32. item=record
  33. typ:types;
  34. ref:integer
  35. end;
  36. var ch:char; { last character read }
  37. sym:symbol; { last symbol read}
  38. id:alfa; { last identifier read 10}
  39. num:integer; { last number read }
  40. cc:integer; { character count }
  41. ll:integer; { line length }
  42. kk,err:integer;
  43. line:string[81];
  44. a:alfa;
  45. i:integer;
  46. word:array[1..norw] of alfa;
  47. wsym:array[1..norw] of symbol;
  48. ssym:array[char] of symbol;
  49. mnemonic:array[opcod] of string[5];
  50. declbegsys,statbegsys,facbegsys,constbegsys,typebegsys:symset;
  51. nametab:array[0..txmax] of { name table }
  52. record
  53. name:alfa;
  54. kind:
  55. oobject ;
  56. typ: types;
  57. lev: 0..levmax;
  58. normal:boolean;
  59. ref:index;
  60. link:index;
  61. case oobject of
  62. variable,prosedure:(adr:integer);
  63. konstant :(val:integer);
  64. typel :(size:integer);
  65. end;
  66. tx: integer; { index of nametab}
  67. atab:array[1..amax] of { array information table }
  68. record
  69. inxtyp,eltyp:types;
  70. elref,low,high,elsize,size:index;
  71. end;
  72. ax:integer; {index of atab }
  73. btab:array[0..bmax] of { block information table }
  74. record
  75. last,lastpar,psize,vsize:index;
  76. end;
  77. bx:integer; { index of btab }
  78. display:array[0..levmax] of integer;
  79. code:array[0..cxmax] of instruction;
  80. cx:integer; { code allocation index }
  81. labtab:array[0..100] of integer;
  82. lx:integer;
  83. {********************************************************}
  84. sfile:text; { source program file }
  85. sfilename:string; { source program file name }
  86. fcode:file of instruction;
  87. labfile:file of integer;
  88. listfile :text;
  89. listfilename:string;
  90. dir:dirstr;
  91. name:namestr;
  92. ext:extstr;
  93. {*********************************************************}
  94. procedure initial;
  95. begin
  96. word[ 1]:='and ';
  97. word[ 2]:='array ';
  98. word[ 3]:='begin ';
  99. word[ 4]:='call ';
  100. word[ 5]:='case ';
  101. word[ 6]:='const ';
  102. word[ 7]:='do ';
  103. word[ 8]:='else ';
  104. word[ 9]:='end ';
  105. word[10]:='for ';
  106. word[11]:='function ';
  107. word[12]:='if ';
  108. word[13]:='mod ';
  109. word[14]:='not ';
  110. word[15]:='of ';
  111. word[16]:='or ';
  112. word[17]:='procedure ';
  113. word[18]:='program ';
  114. word[19]:='repeat ';
  115. word[20]:='then ';
  116. word[21]:='to ';
  117. word[22]:='type ';
  118. word[23]:='until ';
  119. word[24]:='var ';
  120. word[25]:='while ';
  121. wsym[ 1]:=andsym;
  122. wsym[ 2]:=arraysym;
  123. wsym[ 3]:=beginsym;
  124. wsym[ 4]:=callsym;
  125. wsym[ 5]:=casesym;
  126. wsym[ 6]:=constsym;
  127. wsym[ 7]:=dosym;
  128. wsym[ 8]:=elsesym;
  129. wsym[ 9]:=endsym;
  130. wsym[10]:=forsym;
  131. wsym[11]:=functionsym;
  132. wsym[12]:=ifsym;
  133. wsym[13]:=modsym;
  134. wsym[14]:=notsym;
  135. wsym[15]:=ofsym;
  136. wsym[16]:=orsym;
  137. wsym[17]:=procsym;
  138. wsym[18]:=programsym;
  139. wsym[19]:=repeatsym;
  140. wsym[20]:=thensym;
  141. wsym[21]:=tosym;
  142. wsym[22]:=typesym;
  143. wsym[23]:=untilsym;
  144. wsym[24]:=varsym;
  145. wsym[25]:=whilesym;
  146. ssym['+']:=plus; ssym['-']:=minus;
  147. ssym['*']:=times; ssym['/']:=divsym;
  148. ssym['[']:=lbrack; ssym[']']:=rbrack;
  149. ssym['(']:=lparen; ssym[')']:=rparen;
  150. ssym['=']:=eql; ssym[',']:=comma;
  151. ssym['.']:=period;
  152. ssym['<']:=lss; ssym['>']:=gtr;
  153. ssym[';']:=semicolon;
  154. mnemonic[lit]:='LIT '; mnemonic[lod]:='LOD ';
  155. mnemonic[sto]:='STO '; mnemonic[cal]:='CAL ';
  156. mnemonic[jmp]:='JMP '; mnemonic[jpc]:='JPC ';
  157. mnemonic[red]:='RED '; mnemonic[wrt]:='WRT ';
  158. mnemonic[ilod]:='ILOD '; mnemonic[loda]:='LODA ';
  159. mnemonic[lodt]:='LODt '; mnemonic[lodb]:='LODB ';
  160. mnemonic[cpyb]:='COPYB '; mnemonic[endp]:='ENDP ';
  161. mnemonic[retp]:='RETP '; mnemonic[udis]:='ADIS ';
  162. mnemonic[mus]:='MUS '; mnemonic[add]:='ADD ';
  163. mnemonic[sub]:='SUB '; mnemonic[mult]:='MULT ';
  164. mnemonic[idiv]:='DDIV '; mnemonic[eq]:='EQ ';
  165. mnemonic[ne]:='NE '; mnemonic[ls]:='LS ';
  166. mnemonic[le]:='LE '; mnemonic[gt]:='GT ';
  167. mnemonic[ge]:='GE '; mnemonic[opac]:='OPAC ';
  168. mnemonic[entp]:='ENTP'; mnemonic[imod]:='IMOD ';
  169. mnemonic[ands]:='ANDS'; mnemonic[ors]:='ORS ';
  170. mnemonic[nots]:='NOTS';
  171. declbegsys:=[constsym,varsym,typesym,procsym];
  172. statbegsys:=[beginsym,callsym,ifsym,whilesym,casesym,repeatsym,untilsym,forsym];
  173. facbegsys :=[ident,intcon,lparen,notsym,charcon];
  174. typebegsys:=[ident,arraysym];
  175. constbegsys:=[plus,minus,intcon,charcon,ident];
  176. err:=0; a[0]:=#10;
  177. display[0]:=0;
  178. cc:=0; cx:=0; ll:=0; ch:=' '; kk:=al; bx:=1; tx:=-1;
  179. lx:=0
  180. end; {init}
  181. procedure enterpreid;
  182. procedure enter(x0:alfa;x1:oobject;
  183. x2:types;x3:integer);
  184. begin
  185. tx:=tx+1;
  186. with nametab[tx] do
  187. begin
  188. name:=x0;link:=tx-1;kind:=x1;
  189. typ:=x2;ref:=0;normal:=true;
  190. lev:=0;
  191. case kind of
  192. variable,prosedure: adr:=x3;
  193. konstant: val:=x3;
  194. typel: size:=x3
  195. end
  196. end
  197. end;
  198. begin
  199. enter(' ',variable,notyp,0); { sentinel }
  200. enter('char ',typel, chars,1);
  201. enter('integer ',typel,ints, 1);
  202. enter('boolean ',typel,bool, 1);
  203. enter('false ',konstant,bool, 0);
  204. enter('true ',konstant,bool, 1);
  205. enter('read ',prosedure,notyp,1);
  206. enter('write ',prosedure,notyp,2);
  207. btab[0].last:=tx; btab[0].lastpar:=1;
  208. btab[0].psize:=0; btab[0].vsize:=0
  209. end; {enterprid}
  210. procedure error(n:integer);
  211. begin writeln(listfile,'****',' ':cc-1,'^',n:2);
  212. err:=err+1
  213. end; { error }
  214. procedure getsym;
  215. label 1;
  216. var i,k,j:integer;
  217. procedure getch;
  218. begin
  219. if cc=ll then { get character to end of line }
  220. { read next line }
  221. begin
  222. if eof(sfile) then
  223. begin
  224. writeln('program incomplete');
  225. close(sfile);
  226. exit;
  227. end;
  228. ll:=0; cc:=0; write(listfile,cx:4,' '); {print code address }
  229. while not eoln(sfile) do
  230. begin
  231. ll:=ll+1; read(sfile,ch); write(listfile,ch);
  232. line[ll]:=ch
  233. end;
  234. writeln(listfile); readln(sfile);
  235. ll:=ll+1; line[ll]:=' ' {process end-line}
  236. end;
  237. cc:=cc+1; ch:=line[cc]
  238. end; { getch }
  239. begin {getsym}
  240. 1: while ch=' ' do getch;
  241. case ch of
  242. 'a','b','c','d','e','f','g','h','i','j','k','l','m','n',
  243. 'o','p','q','r','s','t','u','v','w','x','y','z':
  244. begin { identifier or reserved(关键字) word }
  245. k:=0;
  246. repeat
  247. if k<al then
  248. begin k:=k+1; a[k]:=ch end;
  249. getch
  250. until not (ch in ['a'..'z','0'..'9']);
  251. if k>=kk then kk:=k { kk: last identifier length }
  252. else
  253. repeat
  254. a[kk]:=' '; kk:=kk-1
  255. until kk=k;
  256. id:=a; i:=1; j:=norw; { binary search reserved word table }
  257. repeat
  258. k:=(i+j) div 2;
  259. if id<=word[k] then j:=k-1;
  260. if id>=word[k] then i:=k+1;
  261. until i>j;
  262. if i-1>j then sym:=wsym[k]
  263. else sym:=ident
  264. end;
  265. '{' :
  266. begin
  267. repeat
  268. getch
  269. until ch = '}';
  270. getch;
  271. goto 1
  272. end;
  273. '0','1','2','3','4','5','6','7','8','9':
  274. begin { number }
  275. k:=0; num:=0; sym:=intcon;
  276. repeat
  277. num:=10*num+(ord(ch)-ord('0'));
  278. k:=k+1; getch
  279. until not (ch in ['0'..'9']);
  280. if k>nmax then error(47)
  281. end;
  282. ':':
  283. begin
  284. getch;
  285. if ch='=' then
  286. begin sym:=becomes; getch end
  287. else sym:=colon
  288. end ;
  289. '<' :
  290. begin
  291. getch;
  292. if ch='=' then
  293. begin sym:=leq; getch end
  294. else
  295. if ch='>' then
  296. begin sym:=neq; getch end
  297. else sym:=lss
  298. end ;
  299. '>' :
  300. begin
  301. getch;
  302. if ch='=' then
  303. begin sym:=geq; getch end
  304. else sym:=gtr
  305. end ;
  306. '.' :
  307. begin
  308. getch;
  309. if ch='.'
  310. then begin
  311. sym:=colon;getch
  312. end
  313. else sym:=period
  314. end;
  315. '''' :
  316. begin
  317. getch;
  318. sym:=charcon;num:=ord(ch);
  319. getch;
  320. if ch='''' then getch
  321. else error(48)
  322. end;
  323. '+','-','*','/','(',')','=','[',']',';',',':
  324. begin
  325. sym:=ssym[ch];getch
  326. end;
  327. else
  328. begin
  329. error(0); getch;
  330. goto 1
  331. end
  332. end { case }
  333. end; { getsym }
  334. procedure enterarray (tp:types ; l,h:integer);
  335. begin
  336. if l>h then error(14);
  337. if ax=amax then
  338. begin
  339. error(2);
  340. writeln('too many arrays in program ');
  341. close(sfile);
  342. close(listfile);
  343. exit
  344. end
  345. else begin
  346. ax:=ax+1;
  347. with atab[ax] do
  348. begin
  349. inxtyp:=tp; low:=l; high:=h
  350. end
  351. end
  352. end; { enterarray }
  353. procedure enterblock;
  354. begin
  355. if bx=bmax then
  356. begin
  357. error(3);
  358. writeln('too many procedure in program ');
  359. close(sfile);
  360. close(listfile);
  361. exit
  362. end
  363. else begin
  364. bx:=bx+1; btab[bx].last:=0; btab[bx].lastpar:=0
  365. end
  366. end; { enterblock }
  367. procedure gen(x:opcod; y,z:integer); {产生代码程序gen}
  368. begin
  369. if cx>cxmax then
  370. begin
  371. error(49);
  372. writeln('program too long');
  373. close(sfile);
  374. close(listfile);
  375. exit
  376. end;
  377. with code[cx] do
  378. begin
  379. f:=x; l:=y; a:=z
  380. end;
  381. cx:=cx+1
  382. end; { gen }
  383. procedure test(s1,s2:symset;n:integer);
  384. begin
  385. if not (sym in s1) then
  386. begin
  387. error(n); s1:=s1+s2;
  388. while not (sym in s1) do getsym
  389. end
  390. end; { test }
  391. procedure block( fsys:symset;level:integer);
  392. type
  393. constrec=record
  394. tp:types;
  395. i:integer
  396. end;
  397. var dx:integer; { data allocation index }
  398. tx0:integer; { initial table index }
  399. cx0:integer; { initial code index }
  400. prt,prb:integer;
  401. procedure enter( k:oobject);
  402. var j,l:integer;
  403. begin
  404. if tx=txmax
  405. then begin
  406. error(1);
  407. writeln('program too long');
  408. close(sfile);
  409. close(listfile);
  410. exit
  411. end
  412. else begin
  413. nametab[0].name:=id;
  414. j:=btab[display[level]].last; l:=j;
  415. while nametab[j].name<>id do j:=nametab[j].link;
  416. if j<>0
  417. then error(l)
  418. else begin
  419. tx:=tx+1;
  420. with nametab[tx] do
  421. begin
  422. name:=id; link:=l;
  423. kind:=k; typ:=notyp; ref:=0;
  424. lev:=level; normal:=false;
  425. case kind of
  426. variable,prosedure: adr:=0;
  427. konstant: val:=0;
  428. typel: size:=0
  429. end { initial value }
  430. end;
  431. btab[display[level]].last:=tx
  432. end
  433. end
  434. end; { enter }
  435. function position(id:alfa):integer;
  436. var i,j:integer;
  437. begin
  438. nametab[0].name:=id; j:=level;
  439. repeat
  440. i:=btab[display[j]].last;
  441. while nametab[i].name<>id do
  442. i:=nametab[i].link;
  443. j:=j-1
  444. until (j<0) or (i<>0);
  445. if (i=0) then error(10);
  446. position:=i
  447. end; { position }
  448. procedure constant(fsys:symset; var c:constrec);
  449. var x,sign:integer;
  450. begin
  451. c.tp:=notyp; c.i:=0;
  452. test(constbegsys,fsys,50);
  453. if sym in constbegsys
  454. then begin
  455. if sym=charcon
  456. then begin
  457. c.tp:=chars; c.i:=num;
  458. getsym
  459. end else
  460. begin
  461. sign:=1;
  462. if sym in [plus,minus]
  463. then begin
  464. if sym=minus then sign:=-1;
  465. getsym
  466. end;
  467. if sym=ident
  468. then begin
  469. x:=position(id);
  470. if x<>0
  471. then if nametab[x].kind<>konstant
  472. then error(12)
  473. else begin
  474. c.tp:=nametab[x].typ;
  475. c.i:=sign*nametab[x].val
  476. end;
  477. getsym
  478. end else if sym=intcon
  479. then begin
  480. c.tp:=ints; c.i:=sign*num;
  481. getsym
  482. end
  483. end;
  484. test(fsys,[],6)
  485. end
  486. end; { constant }
  487. procedure typ(fsys:symset;var tp:types; var rf,sz:integer);
  488. var eltp:types;
  489. elrf,x:integer;
  490. elsz,offset,t0,t1:integer;
  491. procedure arraytyp(var aref,arsz:integer);
  492. var eltp:types;
  493. low,high:constrec;
  494. elrf,elsz:integer;
  495. begin
  496. constant([colon,rbrack,rparen,ofsym]+fsys,low);
  497. if (low.tp<>ints) and (low.tp<>chars)
  498. then error(50);
  499. if sym=colon then getsym else error(38);
  500. constant([rbrack,comma,rparen,ofsym]+fsys,high);
  501. if high.tp<>low.tp
  502. then begin
  503. error(40); high.i:=low.i;
  504. end;
  505. enterarray(low.tp,low.i,high.i);
  506. aref:=ax;
  507. if sym=comma
  508. then begin
  509. getsym;
  510. eltp:=arrays;
  511. arraytyp(elrf,elsz)
  512. end else begin
  513. if sym=rbrack
  514. then getsym
  515. else begin
  516. error(28);
  517. if sym=rparen then getsym
  518. end;
  519. if sym=ofsym then getsym else error(17);
  520. typ(fsys,eltp,elrf,elsz)
  521. end;
  522. with atab[aref] do
  523. begin
  524. arsz:=(high-low+1)*elsz; size:=arsz;
  525. eltyp:=eltp; elref:=elrf; elsize:=elsz
  526. end;
  527. end; { arraytyp }
  528. begin { typ }
  529. tp:=notyp; rf:=0; sz:=0;
  530. test(typebegsys,fsys,10);
  531. if sym in typebegsys
  532. then begin
  533. if sym=ident
  534. then begin
  535. x:=position(id);
  536. if x<>0
  537. then with nametab[x] do
  538. if kind<>typel
  539. then error(19)
  540. else begin
  541. tp:=typ;rf:=ref;sz:=size;
  542. if tp=notyp then error(18);
  543. end;
  544. getsym;
  545. end else if sym=arraysym
  546. then begin
  547. getsym;
  548. if sym=lbrack
  549. then getsym
  550. else begin
  551. error(16);
  552. if sym=lparen
  553. then getsym
  554. end;
  555. tp:=arrays;
  556. arraytyp(rf,sz)
  557. end ;
  558. test(fsys,[],13)
  559. end
  560. end; {typ}
  561. procedure paramenterlist; {formal parameter list}
  562. var
  563. tp:types;
  564. valpar:boolean;
  565. rf,sz,x,t0:integer;
  566. begin
  567. getsym;
  568. tp:=notyp;rf:=0;sz:=0;
  569. test([ident,varsym],fsys+[rparen],7);
  570. while sym in [ident,varsym] do
  571. begin
  572. if sym <> varsym
  573. then valpar:=true
  574. else begin
  575. getsym;
  576. valpar:=false
  577. end;
  578. t0:=tx;
  579. if sym=ident
  580. then begin
  581. enter(variable);
  582. getsym
  583. end else error(22);
  584. while sym=comma do
  585. begin
  586. getsym;
  587. if sym=ident
  588. then begin
  589. enter(variable);
  590. getsym
  591. end else error(22);
  592. end;
  593. if sym=colon
  594. then begin
  595. getsym;
  596. if sym <> ident
  597. then error(22)
  598. else begin
  599. x :=position(id); getsym;
  600. if x<>0
  601. then with nametab[x] do
  602. if kind <> typel
  603. then error(19)
  604. else begin
  605. tp:= typ; rf:=ref;
  606. if valpar then sz:=size else sz:=1
  607. end;
  608. end;
  609. test ([semicolon,rparen],[comma,ident]+fsys,14)
  610. end else error(24);
  611. while t0 < tx do
  612. begin
  613. t0 :=t0+1;
  614. with nametab[t0] do
  615. begin
  616. typ :=tp;ref :=rf;
  617. adr :=dx;lev :=level;
  618. normal :=valpar;
  619. dx :=dx+sz
  620. end
  621. end;
  622. if sym <> rparen
  623. then begin
  624. if sym=semicolon
  625. then getsym
  626. else begin
  627. error(23);
  628. if sym=comma then getsym
  629. end;
  630. test([ident,varsym],[rparen]+fsys,13)
  631. end
  632. end {while};
  633. if sym=rparen
  634. then begin
  635. getsym;
  636. test([semicolon],fsys,13)
  637. end else error(25)
  638. end {parameterlist};
  639. procedure constdeclaration;
  640. var c:constrec;
  641. begin
  642. if sym=ident then
  643. begin
  644. enter(konstant);
  645. getsym;
  646. if sym = eql
  647. then getsym
  648. else
  649. begin
  650. error(26);
  651. if sym=becomes then getsym
  652. end;
  653. constant([semicolon,comma,ident]+fsys,c);
  654. nametab[tx].typ:=c.tp;
  655. nametab[tx].ref:=0;
  656. nametab[tx].val:=c.i;
  657. if sym=semicolon then getsym else error(23)
  658. end
  659. else error(22);
  660. test(fsys+[ident],[],13)
  661. end; { constdeclaration }
  662. procedure typedeclaration;
  663. var
  664. tp:types;
  665. rf,sz,t1:integer;
  666. begin
  667. if sym=ident then
  668. begin
  669. enter(typel);
  670. t1:=tx;
  671. getsym;
  672. if sym = eql then getsym
  673. else begin
  674. error(26);
  675. if sym=becomes then getsym;
  676. end;
  677. typ ([semicolon,comma,ident]+fsys,tp,rf,sz);
  678. nametab[tx].typ:=tp;
  679. nametab[tx].ref:=rf;
  680. nametab[tx].size:=sz;
  681. if sym=semicolon then getsym else error(23)
  682. end
  683. else error(22);
  684. test(fsys+[ident],[],13)
  685. end; { typedeclaration }
  686. procedure vardeclaration;
  687. var tp:types;
  688. t0,t1,rf,sz:integer;
  689. begin
  690. if sym=ident then
  691. begin
  692. t0:=tx;
  693. enter(variable); getsym;
  694. while sym = comma do
  695. begin
  696. getsym;
  697. if sym =ident
  698. then begin
  699. enter(variable);getsym;
  700. end else error(22);
  701. end;
  702. if sym = colon then getsym else error(24);
  703. t1:=tx;
  704. typ ([semicolon,comma,ident]+fsys,tp,rf,sz);
  705. while t0 < t1 do
  706. begin
  707. t0:=t0+1;
  708. with nametab[t0] do
  709. begin
  710. typ:=tp; ref:=rf;
  711. lev:=level; adr:=dx;
  712. normal:=true;
  713. dx:=dx+sz
  714. end
  715. end;
  716. if sym=semicolon then getsym else error(23)
  717. end
  718. else error(22);
  719. test(fsys+[ident],[],13)
  720. end; { vardeclaration }
  721. procedure procdeclaration;
  722. begin
  723. getsym;
  724. if sym <> ident
  725. then begin
  726. error(22); id:=' '
  727. end;
  728. enter(prosedure);
  729. nametab[tx].normal:=true;
  730. getsym;
  731. block([semicolon]+fsys,level+1);
  732. if sym = semicolon then getsym else error(23);
  733. end; {procdeclaration}
  734. procedure listcode;
  735. var i:integer;
  736. begin
  737. for i:=cx0 to cx-1 do
  738. with code[i] do
  739. writeln(listfile,i:4,mnemonic[f]:7,l:3,a:5)
  740. end; { listcode }
  741. procedure statement(fsys:symset);
  742. var i,cx1,cx2,cx3:integer;
  743. x:item;
  744. procedure arrayelement(fsys:symset;var x:item); forward;
  745. procedure expression(fsys:symset;var x: item);
  746. var relop:symbol;
  747. y:item;
  748. procedure simpleexpression(fsys:symset;var x:item);
  749. var addop:symbol;
  750. y:item;
  751. procedure term(fsys:symset;var x: item);
  752. var mulop:symbol;
  753. y:item;
  754. procedure factor(fsys:symset;var x:item);
  755. var i:integer;
  756. begin
  757. x.typ:=notyp;
  758. x.ref:=0;
  759. test(facbegsys,fsys,13);
  760. if sym in facbegsys then { facbegsys :=[ident,intcon,lparen,notsym,charcon];}
  761. begin
  762. case sym of
  763. ident :
  764. begin
  765. i:=position(id);
  766. getsym;
  767. if i=0 then error(10)
  768. else
  769. with nametab[i] do
  770. case kind of
  771. konstant: begin
  772. x.typ:=typ;
  773. x.ref:=0;
  774. gen(lit,0,val);
  775. end;
  776. variable:
  777. begin
  778. x.typ:=typ;
  779. x.ref:=ref;
  780. if (typ = ints) or (typ = bool) or(typ=chars)
  781. then if normal then gen(lod,lev,adr)
  782. else gen(ilod,lev,adr)
  783. else if typ=arrays then
  784. begin
  785. if normal then gen(loda,lev,adr)
  786. else gen(lod,lev,adr);
  787. if sym = lbrack
  788. then arrayelement(fsys,x);
  789. if x.typ <> arrays
  790. then gen(lodt,0,0)
  791. end
  792. end;
  793. prosedure,typel:error(41)
  794. end;
  795. end ;
  796. intcon,charcon :
  797. begin
  798. if sym = intcon then x.typ:=ints
  799. else x.typ:=chars;
  800. x.ref:=0;
  801. gen(lit,0,num);
  802. getsym
  803. end;
  804. lparen :
  805. begin
  806. getsym;
  807. expression([rparen]+fsys,x);
  808. if sym=rparen then getsym
  809. else error(25)
  810. end;
  811. notsym :
  812. begin
  813. getsym;
  814. factor(fsys,x);
  815. if x.typ = bool
  816. then gen(nots ,0,0)
  817. else error(43)
  818. end;
  819. end ;{ case }
  820. test(fsys+[rbrack,rparen],facbegsys,23)
  821. end { of if }
  822. end; { factor }
  823. begin { term }
  824. factor(fsys+[times,divsym,modsym,andsym],x);
  825. while sym in [times,divsym,modsym,andsym] do
  826. begin
  827. mulop:=sym; getsym;
  828. factor(fsys+[times,divsym,modsym,andsym],y);
  829. if x.typ<>y.typ
  830. then begin
  831. error(40);
  832. x.typ:=notyp;
  833. x.ref:=0
  834. end
  835. else
  836. begin
  837. if mulop=times then
  838. if x.typ = ints
  839. then gen(mult,0,0)
  840. else error(43);
  841. if mulop=divsym then
  842. if x.typ = ints
  843. then gen(idiv,0,0)
  844. else error(43);
  845. if mulop=modsym then
  846. if x.typ = ints
  847. then gen(imod,0,0)
  848. else error(43);
  849. if mulop=andsym then
  850. if x.typ = bool
  851. then gen(ands,0,0)
  852. else error(43)
  853. end
  854. end
  855. end; { term}
  856. begin { simpleexpression }
  857. if sym in [plus,minus] then
  858. begin
  859. addop:=sym; getsym;
  860. term(fsys+[plus,minus,orsym],x);
  861. if addop=minus then gen(mus,0,0)
  862. end else term(fsys+[plus,minus,orsym],x);
  863. while sym in [plus,minus,orsym] do
  864. begin addop:=sym; getsym;
  865. term(fsys+[plus,minus,orsym],y);
  866. if x.typ<>y.typ
  867. then begin
  868. error(40);
  869. x.typ:=notyp;
  870. x.ref:=0
  871. end
  872. else
  873. begin
  874. if addop=plus then
  875. if x.typ = ints
  876. then gen(add,0,0)
  877. else error(43);
  878. if addop=minus then
  879. if x.typ = ints
  880. then gen(sub,0,0)
  881. else error(43);
  882. if addop=orsym then
  883. if x.typ = bool
  884. then gen(ors,0,0)
  885. else error(43)
  886. end
  887. end
  888. end; { simpleexpression }
  889. begin {expression}
  890. simpleexpression([eql,neq,lss,gtr,leq,geq]+fsys,x);
  891. while (sym in [eql,neq,lss,leq,gtr,geq]) do
  892. begin
  893. relop:=sym; getsym; simpleexpression(fsys,y);
  894. if x.typ<> y.typ
  895. then error(40);
  896. case relop of
  897. eql:gen(eq,0,0);
  898. neq:gen(ne,0,0);
  899. lss:gen(ls,0,0);
  900. geq:gen(ge,0,0);
  901. gtr:gen(gt,0,0);
  902. leq:gen(le,0,0)
  903. end;
  904. x.typ:=bool
  905. end
  906. end; { expression }
  907. procedure arrayelement(fsys:symset;var x:item);
  908. var cc:integer;
  909. addr,p:index;
  910. y:item;
  911. begin
  912. p:=x.ref;
  913. if sym=lbrack then
  914. begin
  915. repeat
  916. getsym;
  917. expression(fsys+[comma],y);
  918. if x.typ <> arrays then error(40)
  919. else
  920. begin
  921. if y.typ <> atab[p].inxtyp then error(44);
  922. gen(lit,0,atab[p].low);
  923. gen(sub,0,0);
  924. gen(lit,1,atab[p].elsize);
  925. gen(mult,0,0);
  926. gen(add,0,0);
  927. x.typ:=atab[p].eltyp;
  928. x.ref:=atab[p].elref;
  929. p:=atab[p].elref;
  930. end
  931. until sym <> comma;
  932. if sym=rbrack then getsym else error(28);
  933. end else error(16);
  934. test(fsys,[],13);
  935. end; {arrayelement}
  936. procedure assignment;
  937. var x,y:item;
  938. begin
  939. i:=position(id);
  940. if i=0 then error(10)
  941. else
  942. if nametab[i].kind<>variable then
  943. begin { giving value to non-variation }
  944. error(30); i:=0
  945. end;
  946. getsym;
  947. x.typ:=nametab[i].typ;
  948. x.ref:=nametab[i].ref;
  949. with nametab[i] do
  950. if normal
  951. then gen(loda,lev,adr)
  952. else gen(lod,lev,adr);
  953. if sym = lbrack
  954. then arrayelement(fsys+[becomes],x);
  955. if sym = becomes then getsym
  956. else begin
  957. error(33);
  958. if sym=eql then getsym
  959. end;
  960. expression(fsys,y);
  961. if x.typ <> y.typ then error(40)
  962. else
  963. if x.typ = arrays
  964. then if x.ref = y.ref
  965. then gen(cpyb,0,atab[x.ref].size)
  966. else error(40)
  967. else gen(sto,0,0);
  968. end;
  969. procedure ifstatement;
  970. var x:item;
  971. begin
  972. getsym; expression([thensym,dosym]+fsys,x);
  973. if x.typ <> bool then error(34);
  974. if sym=thensym then getsym else error(35);
  975. cx1:=cx; gen(jpc,0,0);
  976. statement(fsys+[elsesym]);
  977. if sym = elsesym
  978. then begin
  979. getsym;
  980. cx2:=cx; gen(jmp,0,0);
  981. code[cx1].a:=cx;
  982. labtab[lx]:=cx;lx:=lx+1;
  983. statement(fsys);
  984. code[cx2].a:=cx;
  985. labtab[lx]:=cx;lx:=lx+1;
  986. end
  987. else
  988. begin
  989. code[cx1].a:=cx;
  990. labtab[lx]:=cx;lx:=lx+1;
  991. end
  992. end; {ifstatement}
  993. procedure casestatement; {case}
  994. var x:item;
  995. coni,conj:integer;
  996. begin
  997. getsym;cx1:=cx;
  998. expression([ofsym]+fsys,x);cx2:=cx;
  999. if (x.typ = ints) or (x.typ = chars)then
  1000. begin
  1001. if sym=ofsym then
  1002. begin
  1003. getsym;conj:=0;
  1004. while sym<>elsesym do
  1005. begin
  1006. if (sym = intcon) or (sym = charcon) then
  1007. begin
  1008. coni:=cx1;
  1009. if conj<>0 then
  1010. begin
  1011. while coni<cx2 do
  1012. begin
  1013. code[cx]:=code[coni];
  1014. cx:=cx+1;
  1015. coni:=coni+1;
  1016. end
  1017. end;
  1018. conj:=1;
  1019. gen(lit,0,num);
  1020. coni:=cx1;
  1021. end
  1022. else error(12);
  1023. getsym;
  1024. if sym=colon then
  1025. begin
  1026. getsym;
  1027. gen(eq,0,0);
  1028. cx2:=cx;
  1029. gen(jpc,0,0);
  1030. statement([semicolon]+fsys);
  1031. if sym=semicolon then
  1032. begin
  1033. getsym;
  1034. labtab[lx]:=cx;lx:=lx+1;
  1035. gen(jmp,0,0);
  1036. code[cx2].a:=cx
  1037. end
  1038. else error(23)
  1039. end
  1040. else error(24){colon}
  1041. end;
  1042. if sym=elsesym then
  1043. begin
  1044. getsym;
  1045. statement([endsym]+fsys);
  1046. lx:=lx-1;
  1047. while lx>=0 do
  1048. begin code[labtab[lx]].a:=cx;
  1049. lx:=lx-1
  1050. end
  1051. end;
  1052. if sym=endsym then getsym
  1053. else error(36)
  1054. end
  1055. else error(17)
  1056. end
  1057. end;
  1058. procedure compound;
  1059. begin
  1060. getsym; statement([semicolon,endsym]+fsys);
  1061. while sym in ([semicolon]+statbegsys) do
  1062. begin
  1063. if sym=semicolon then getsym else error(23);
  1064. statement([semicolon,endsym]+fsys)
  1065. end;
  1066. if sym=endsym then getsym else error(36)
  1067. end; {compound}
  1068. procedure whilestatement;
  1069. var x:item;
  1070. begin
  1071. getsym;
  1072. labtab[lx]:=cx;lx:=lx+1;
  1073. cx1:=cx; expression([dosym]+fsys,x);
  1074. if x.typ <> bool then error(34);
  1075. cx2:=cx; gen(jpc,0,0);
  1076. if sym=dosym then getsym else error(37);
  1077. statement(fsys); gen(jmp,0,cx1); code[cx2].a:=cx;
  1078. labtab[lx]:=cx;lx:=lx+1
  1079. end;
  1080. procedure repeatstatement;{repeat}
  1081. var x:item;
  1082. begin
  1083. getsym;cx1:=cx; labtab[lx]:=cx;lx:=lx+1;
  1084. statement([untilsym]+fsys);
  1085. if sym<>semicolon then error(23);
  1086. getsym;
  1087. while (not (sym in ([untilsym]))) do
  1088. begin
  1089. statement([untilsym]+fsys);
  1090. if sym<>semicolon then error(23);
  1091. getsym
  1092. end;
  1093. if sym=untilsym then
  1094. begin
  1095. getsym;
  1096. expression([endsym]+fsys,x);
  1097. if x.typ <> bool then error(34);
  1098. gen(jpc,0,cx1);labtab[lx]:=cx;lx:=lx+1
  1099. end
  1100. end;
  1101. procedure forstatement;{for}
  1102. var x,ini,fin:item;
  1103. begin
  1104. getsym;
  1105. if sym=ident then
  1106. begin
  1107. i:=position(id);getsym;
  1108. if i=0 then error(10)
  1109. else
  1110. if nametab[i].kind<>variable then
  1111. begin
  1112. error(30);i:=0
  1113. end
  1114. else
  1115. begin
  1116. x.typ:=nametab[i].typ;
  1117. x.ref:=nametab[i].ref;
  1118. if nametab[i].normal
  1119. then gen(loda,nametab[i].lev,nametab[i].adr)
  1120. else gen(lod,nametab[i].lev,nametab[i].adr)
  1121. end;
  1122. if sym=becomes then
  1123. begin
  1124. getsym;
  1125. expression([tosym]+fsys,ini);
  1126. if ini.typ<>ints then error(12)
  1127. else begin
  1128. gen(sto,0,0);
  1129. if sym=tosym then
  1130. begin
  1131. getsym;cx1:=cx;labtab[lx]:=cx;lx:=lx+1;
  1132. gen(loda,nametab[i].lev,nametab[i].adr);
  1133. gen(lodt,0,0);
  1134. expression([dosym]+fsys,fin);
  1135. if sym=dosym then
  1136. begin
  1137. gen(le,0,0);
  1138. cx2:=cx;labtab[lx]:=cx;lx:=lx+1;
  1139. gen(jpc,0,0);
  1140. getsym;
  1141. statement(fsys);
  1142. if nametab[i].normal then
  1143. begin
  1144. gen(loda,nametab[i].lev,nametab[i].adr);
  1145. gen(loda,nametab[i].lev,nametab[i].adr);
  1146. gen(lodt,0,0)
  1147. end
  1148. else gen(lod,nametab[i].lev,nametab[i].adr);
  1149. gen(lit,0,1);
  1150. gen(add,0,0);
  1151. gen(sto,0,0);
  1152. gen(jmp,0,cx1);
  1153. code[cx2].a:=cx
  1154. end
  1155. end
  1156. end
  1157. end
  1158. end
  1159. else error(33)
  1160. end;
  1161. procedure call;
  1162. var x: item;
  1163. lastp,cp,i,j,k:integer;
  1164. procedure stanproc(i:integer);
  1165. var n:integer;
  1166. begin
  1167. if i =6 then
  1168. begin { read }
  1169. getsym;
  1170. if sym=lparen then
  1171. begin
  1172. repeat
  1173. getsym;
  1174. if sym=ident then
  1175. begin
  1176. n:=position(id); getsym;
  1177. if n=0 then error(10)
  1178. else
  1179. if nametab[n].kind<>variable then
  1180. begin error(30); n:=0 end
  1181. else
  1182. begin
  1183. x.typ:=nametab[n].typ;
  1184. x.ref:=nametab[n].ref;
  1185. if nametab[n].normal
  1186. then gen(loda,nametab[n].lev,nametab[n].adr)
  1187. else gen(lod,nametab[n].lev,nametab[n].adr);
  1188. if sym = lbrack
  1189. then arrayelement(fsys+[comma],x);
  1190. if x.typ = ints
  1191. then gen(red,0,0)
  1192. else if x.typ = chars
  1193. then gen(red,0,1)
  1194. else error(43)
  1195. end
  1196. end
  1197. else error(22)
  1198. until sym<>comma;
  1199. if sym<>rparen then error(25)
  1200. else getsym
  1201. end
  1202. else error(32)
  1203. end
  1204. else
  1205. if i = 7 then
  1206. begin { write }
  1207. getsym;
  1208. if sym=lparen then
  1209. begin
  1210. repeat
  1211. getsym;
  1212. expression([rparen,comma]+fsys,x);
  1213. if x.typ = ints
  1214. then gen(wrt,0,0)
  1215. else if x.typ = chars
  1216. then gen(wrt,0,1)
  1217. else error(43)
  1218. until sym<>comma;
  1219. if sym<>rparen then error(25);
  1220. getsym
  1221. end
  1222. else error(32)
  1223. end
  1224. end; { standproc }
  1225. begin { call }
  1226. getsym;
  1227. if sym = ident then
  1228. begin
  1229. i:=position(id);
  1230. if nametab[i].kind = prosedure then
  1231. begin
  1232. if nametab[i].lev = 0 then stanproc(i)
  1233. else begin
  1234. getsym;
  1235. gen(opac,0,0); {open active record}
  1236. lastp :=btab[nametab[i].ref].lastpar;
  1237. cp :=i;
  1238. if sym=lparen
  1239. then begin {actual parameter list}
  1240. repeat
  1241. getsym;
  1242. if cp>=lastp
  1243. then error(29)
  1244. else begin
  1245. cp :=cp+1;
  1246. if nametab[cp].normal then
  1247. begin {value parameter}
  1248. expression(fsys+[comma,colon,rparen],x);
  1249. if x.typ = nametab[cp].typ then
  1250. begin
  1251. if x.ref <> nametab[cp].ref
  1252. then error(31)
  1253. else if x.typ = arrays
  1254. then gen(lodb,0,atab[x.ref].size)
  1255. end
  1256. else error(31)
  1257. end else begin {variable parameter}
  1258. if sym <> ident
  1259. then error(22)
  1260. else begin
  1261. k:=position(id);
  1262. getsym;
  1263. if k<>0
  1264. then begin
  1265. if nametab[k].kind<>variable then error (30);
  1266. x.typ :=nametab[k].typ;
  1267. x.ref :=nametab[k].ref;
  1268. if nametab[k].normal
  1269. then gen(loda,nametab[k].lev,nametab[k].adr)
  1270. else gen(lod,nametab[k].lev,nametab[k].adr);
  1271. if sym = lbrack
  1272. then arrayelement(fsys+[comma,rparen],x);
  1273. if (nametab[cp].typ<>x.typ)
  1274. or (nametab[cp].ref<>x.ref)
  1275. then error(31);
  1276. end
  1277. end
  1278. end {variable parameter}
  1279. end;
  1280. test([comma,rparen],fsys,13)
  1281. until sym <> comma;
  1282. if sym=rparen then getsym else error(25)
  1283. end;
  1284. if cp < lastp then error(39);{too few actual parameters}
  1285. gen(cal,nametab[i].lev,nametab[i].adr);
  1286. if nametab[i].lev<level then gen(udis,nametab[i].lev,level)
  1287. end
  1288. end else error(51)
  1289. end else error(22);
  1290. test(fsys+[ident],[],13)
  1291. end {call};
  1292. begin { statement }
  1293. test(statbegsys+[ident],fsys,13);
  1294. if sym=ident then assignment
  1295. else if sym=callsym then call
  1296. else if sym=ifsym then ifstatement
  1297. else if sym=casesym then casestatement
  1298. else if sym=repeatsym then repeatstatement
  1299. else if sym=forsym then forstatement
  1300. else if sym=beginsym then compound
  1301. else if sym=whilesym then whilestatement;
  1302. test(fsys+[elsesym],[],13)
  1303. end; { statement }
  1304. begin { block }
  1305. prt:=tx;
  1306. dx:=3; tx0:=tx; nametab[tx].adr:=cx;
  1307. if level > levmax then error(4);
  1308. enterblock ;
  1309. prb:=bx; display[level]:=bx;
  1310. nametab[prt].typ:=notyp; nametab[prt].ref:=prb;
  1311. if(sym=lparen) and (level>1)
  1312. then
  1313. begin
  1314. paramenterlist;
  1315. if sym=semicolon then getsym
  1316. else error(23)
  1317. end
  1318. else if level>1 then
  1319. if sym=semicolon then getsym
  1320. else error(23);
  1321. btab[prb].lastpar:=tx;
  1322. btab[prb].psize:=dx;
  1323. gen(jmp,0,0); { jump from declaration part to statement part }
  1324. repeat
  1325. if sym=constsym then
  1326. begin
  1327. getsym;
  1328. repeat
  1329. constdeclaration;
  1330. until sym<>ident
  1331. end;
  1332. if sym=typesym then
  1333. begin
  1334. getsym;
  1335. repeat
  1336. typedeclaration;
  1337. until sym<>ident
  1338. end;
  1339. if sym=varsym then
  1340. begin
  1341. getsym;
  1342. repeat
  1343. vardeclaration;
  1344. until sym<>ident;
  1345. end;
  1346. while sym=procsym do procdeclaration;
  1347. test(statbegsys+[ident],declbegsys,13)
  1348. until not (sym in declbegsys);
  1349. code[nametab[tx0].adr].a:=cx; {back enter statement code's start adr. }
  1350. labtab[lx]:=cx;lx:=lx+1;
  1351. with nametab[tx0] do
  1352. begin
  1353. adr:=cx; {code's start address }
  1354. end;
  1355. cx0:=cx;
  1356. gen(entp,level,dx); { block entry }
  1357. statement([semicolon,endsym]+fsys);
  1358. if level>1 then gen(retp,0,0) {return}
  1359. else gen(endp,0,0); { end prograam }
  1360. test(fsys,[],13);
  1361. listcode;
  1362. end; { block }
  1363. {************************************************************************}
  1364. begin { main }
  1365. writeln('Please input source program file name:');
  1366. readln(sfilename);
  1367. assign(sfile,sfilename);
  1368. reset(sfile);
  1369. fsplit(sfilename,dir, name,ext);
  1370. listfilename:=dir +name+'.LST';
  1371. assign(listfile,listfilename);
  1372. rewrite(listfile);
  1373. initial;
  1374. enterpreid;
  1375. getsym;
  1376. if sym = programsym then
  1377. begin
  1378. getsym;
  1379. if sym = ident then
  1380. begin
  1381. getsym;
  1382. if sym = semicolon then getsym
  1383. else error(23)
  1384. end
  1385. else error(22)
  1386. end
  1387. else error(15);
  1388. test(declbegsys+[beginsym],[],13);
  1389. block([period]+declbegsys+statbegsys,1);
  1390. if sym<>period then error(38);
  1391. if err=0 then
  1392. begin
  1393. write('SUCCESS');
  1394. assign(fcode,dir+name+'.pld');
  1395. rewrite(fcode);
  1396. for i:=0 to cx do
  1397. write(fcode,code[i]);
  1398. close(fcode);
  1399. assign(labfile,dir+name+'.lab');
  1400. rewrite(labfile);
  1401. for i:=0 to lx do
  1402. write(labfile,labtab[i]);
  1403. close(labfile)
  1404. end
  1405. else write(err,'ERRORS IN PROGRAM');
  1406. writeln;
  1407. close(sfile);
  1408. close(listfile)
  1409. end. { of whole program }

测试代码

case
  1. program fsj;
  2. var n:integer;
  3. a:char;
  4. begin
  5. n:=2;
  6. a:='f';
  7. case a of
  8. 1: call write(1);
  9. 'f': call write(n);
  10. else call write(2)
  11. end
  12. end.
repeat
  1. program fsj;
  2. var n:integer;
  3. begin
  4. n:=1;
  5. repeat
  6. n:=n+1;
  7. until n=5;
  8. call write(n)
  9. end.
for
  1. program fsj;
  2. var i,sum:integer;
  3. begin
  4. sum:=0;
  5. for i:=3 to 7 do
  6. sum:=sum+i*2;
  7. call write(sum)
  8. end.
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注