, , SPL. , SPL . SPL , , ( SPL) , , . , SPL , . . , , .
, : , , . , , , . get (), lex. , , , lex lx. exam (). lex lx ( get ()). . exam () .
void exam (int lx)
{
if (lex!=lx)
{
printf ( lex=%i lx=%i nst=%i \n, lex, lx, nst);
exit (1);
}
get ();
return;
}
part2.c , , . part1.c. . main() get(); prog();
get().
while (nch!=EOF)
{
}
if (nch = = EOF)
{
lex = EOF;
return;
}
, get() .
, part2. c part1.c , . , , . , . PROG.
1) PROG → (DCONST |DVARB |DFUNK) * eof
void prog()
{
while (lex!=EOF)
{
switch (lex)
{
case IDEN: dfunc(); break;
|
|
case INTL: dvarb(); break;
case CONSTL: dconst(); break;
default: printf( nst=%i. lex=%i \n, nst, lex);
}
}
return;
}
, lex!=EOF, lex. lex IDEN, , INTL CONSTL . , : dfunc(), dvarb(), dconst().
2) DCONST → constl CONS (, CONS)* ;
void dconst()
{
//
// , get();
do
{
get();
cons();
} while (lex = = ,);
exam (;);
return;
}
, constl. , lex constl, prog(). switch (lex) case CONSL dconst(). , CONS, (). , constl . . dconstl - ( get()),
cons(), CONS. lex = =,. , lex==;. exam (;). , exam() get() , , , .
3) CONS → iden = [ + | - ] numb
//
void cons()
{
exam (IDEN);
exam (=);
if (lex = = + || lex = = -)
get();
exam (NUMB);
return;
}
, , lex , . exam(). .. , IDEN, =. + - NUNB.
4) DVARB → intl iden (, iden) * ;
// . INTL prog() // switch (lex). dvarb().
void dvarb()
{
do
{
get();
exam(IDEN);
} while(lex = = ,);
exam(;);
return;
}
get(). , IDEN. exam() get(). , do while get() exam(IDEN). , ,, ;.
5) DFUNC → iden PARAM BODY
// IDEN prog() switch(lex). // get() .
void dfunc()
{
get(); //
param();
body();
return;
}
6) PARAM → ( [ iden (, iden) *] )
param() dfunc() get(). , .
|
|
void param()
{
exam (();
if (lex!=))
{
exan (IDEN);
while (lex = =,)
{
get();
exam (IDEN);
}
}
exam ());
return;
}
, (. exam((). ()). exam() get() . ), IDEN. -, IDEN ,, exam (IDEN). ) .
7) BODY → beginl (DCONST |DVARB) * STML endl
bdy() dfunc() param(). param() exam()). , get(), . BEGINL.
void body()
{
exam (BEGINL);
while(lex = = INTL || lex = = CONSTL)
if (lex = = INTL) dvarb();
else
dconst();
stml();
exam(ENDL);
return;
}
8
8) STML → STAT (; STAT)*
stml() dconst(). exam(;). get(), .
void stml()
{
stat();
while (lex = = ;)
{
get();
stat();
}
return;
}
9) STAT → iden = EXPR | readl iden | pritl EXPR | retrl EXPR | ifl EXPR thenl STML endl | whilel EXPR dol STML endl
stat() . switch (lex).
void stat()
{
switch (lex)
{
case IDEN: get(); exam (=); expr(); break;
case READL: get(); exam (IDEN); break;
case PRITL: get(); expr(); break;
case RETRL: get(); expr(); break;
case IFL: get(); expr(); exam(THENL); stml(); exam(ENDL); break;
case WHILEL: get(); expr(); exam(DOL); stml(); exam(ENDL); break;
default: printf(. stat nst=%i \n, nst);
}
return;
}
10) EXPR → [+|-] TERM ((+|-)TERM)*
//
void expr()
{
if (lex = = + || lex = = -)
get();
term();
while (lex = = + || lex = = -)
{
get();
term();
}
return;
}
11)TERM→FACT ((*|/| %)FACT)*
//
void term();
{
fact();
while(lex = =*||lex = =/||lex = = %)
{
get();
fact();
}
return;
}
12) FACT →(EXPR)|numb| iden [([FCTL])]
void fact()
{
switch(lex)
{
case (: get(); expr();exam()); break;
case NUMB: get(); break;
case IDEN: get(); if(lex = =()
{
get();
if(lex!=))
fctl ();
exam());
}
break;
default: printf ( fact. lex =%d
nst=%d \n,lex, nst);
}
return;
}
fact() get(). , . . get(), . .
13)FTCL →EXPR(,EXPR)*
//
void fctl()
{
expr();
while(lex = = ,)
{
get();
expr();
}
return;
}
9
, SPL - , . .
typedef struct
{
int cod;
int opd;
}
cmd;
(int cod) (int opd). , , .
|
|
,
cmd TCD[300];
, ,
int st[500]. st[0], st[1], st[2] . . .
int cgv = 0;
Ÿ . main().
- . : () (). main() - -2 -1. main(). main() , main(), . 1, 2 , n, - n, , ( ) , .
. .
: t- (top);
sp - ( ).
sp. st[sp+k], k - ( sp). k<0 - (n+2), , -4,-3.
n .
st[sp-2]- .
st[sp-1]- , st[sp] .
k>0.
.
a(x,y,z)
begin
int v,w
end
: x- - (3+2)=-5
y- =-4
z- =-3
v- =1
w- =2
, x,y,z,v,w st[sp-5], st[sp-4], st[sp-3], st[sp+1], st[sp+2].
char TNM [400]
cmd TCD [300]. , int tc=0; tc =0. TCD.
, . - , .
.
typedef struct
{
char * name;
int what;
int val;
}
odc;
, TNM.
int what :
1- ;
2- ;
3- - ;
int val k .
odc TOB [100].
pto . TOB.
odc *pto = TOB;
odc *ptol - . TOB.
odc *ptol = TOB;
TOB int out =1. . out =1, , out =0, .
|
|
.
typedef struct
{
char*name
int isd;
int cpt;
int start;
}
fnd;
fnd TFN[30]. ptf . .
fnd *ptf=TFN.
- , TNM.
TFN[i].isd , . , TFN[i].isd=1, - . TFN[i].start - .
TFN[i].cpt .
10
, , .
.. , . , . .
TOB, TFN TCD, . .
/*newob - TOB */
void newob(char*nm, int wt, int vl)
{
odc*p,*pe;
pe=out? TOB: ptol;
for(p=pto-1: p>=pe; p - -)
if(strcmp(nm,p→name)= =0)
{
puts( );
exit(1);
}
if(pto>= TOB+100)
{
puts( );
exit(1);
}
p→name = nm;
p→what=wt;
p→val=vl;
pto++;
return;
}
out=1, , , out=0, . p>=TOB p>=ptol. , ptol - . , nm , . pto . , , .
/* findob() TOB */
odc *findob(char*nm)
{
odc*p;
for(p=pto-1: p>=TOB; p - -)
if(strcmp(nm,p→name)= =0)
return p;
printf( %s \n, nm);
exit(1);
return p;
}
, , . return p; , - .
TFN
fnd*newfn(char*nm, int df, int cp, int ps)
{
if(ptf>=TFN+30)
{
puts( TFN);
exit(1);
}
ptf→name = nm;
ptf→isd=df;
ptf→cpt=cp;
ptf→start=ps;
return ptf + +;
}
, ptf fnd TFN[30]. , TFN . , ptf .
TFN
fnd*findfn(char*nm)
{
fnd*p;
for(p=ptf-1: p>=TFN; p - -)
if(strcmp(nm,p→name)= =0)
return p;
return NULL;
}
TFN char*nm. , , fnd*p. - .
fnd*eval(char*nm, int cp)
. findfn() , . , newfn(nm,0,cp,-1). , . , , TFN. - .
fnd*eval(char*nm, int cp)
{
fnd*p;
if(!p=findfn(nm))
return newfn(nm,0,cp,-1);
if(p→cpt= =cp)
return p;
printf( %s \n, nm);
exit(1);
return p;
}
exit(1) return p , - .
|
|
void defin(char*nm, int cp, int ad)
{
fnd*p;
int c1,c2;
p=findfn(nm);
if(p)
{
if(p→isd)
{
printf( %s \n,nm);
exit(1);
}
if(p→cpt!=cp)
{
printf( %s \n,nm);
exit(1);
}
p→isd=1;
for(c1=p→start;c1!=-1;c1=c2)
{
c2=TCD[c1].opd;
TCD[c1].opd=ad;
}
p→start=ad;
}// if(p)
else
newfn(nm,1,cp,ad);
return;
}
nm, cp, ad , .
nm TFN. , , . , p→isd=1. , . , TFN[i].start , ,, . 3 , SUM, n .
|
3
defin() for(). p→start TCD, . g en(CAL, p→start).
1. , 1≠-1 . p→start=ad.
, findfn(nm) TFN nm, newfn(nm,1,cp,ad). TFN , .
main()
fnd*fmain()
{
static har nm[]=main;
fnd*pm=NULL;
fnd*p;
for(p=ptf-1;p>=TFN; p - -)
{
if(!p→isd)
{
printf( %s \n, p→name);
exit(1);
}
if(strcmp(nm, p → name)= = 0)
pm=p;
}// for()
if(pm)
return pm;
puts( main);
exit(1);
return pm;
}
r eturn pm; exit(1) , . main() , e xit(1); return pm; .
11
SPL
, , SPL , TCD. . - . 10 . . . - . . , .
enum{OPR,LIT,LDE,LDI,STE,STI,CAL,INI,JMC, JMP};
, OPR .
LIT -, LDE - . .
OPR .
1) OPR 1 - stdin ( ).
OPR 2 - ( stdout).
OPR 3, OPR 4, OPR 5, OPR 6, OPR 7 - +, -,*, /, % . t-1, - t. .
OPR 8 - .
OPR 9 - (return). , . main(), p=-1, . .
OPR 10 .
2) LIT - t.
3) LDE - . - .
4) LDI - .
5) STE - , . , , st [a], .
6) STI - , . st[sp+a], sp- , .
7) CAL - TCD.
8) INI ( ).
9) JMC - TCD.
10) JMP - .
, . - . , .
SPL
, , TFN, TCD.
TNM .
TCD , +b < ><b>+.
val {LIT val}. d {LDE a} {LDI a}. , t.
f(e1,e2,en) TCD <e1><e2><en> {LIT n } {CAL a}, <ei> - ei. {LIT n } . <e>{OPR 8}.
e1 e2 < e1>< e2>{OPR }, =3,4,5,6,7 +,-, *, /, %. e1. - e2. e1 t -1. {OPR }.
SPL d e, d , , <e>{STE a}. <e>{STI a}.
read d {OPR 1}{STE a } d {OPR 1}{STI a} . - .
print e, return e d <e>{OPR 2},<e>{OPR 9 }. e, t, .
if e then s end e . , s , then end. if . ≤0, . TCD <e>{JMC l} <s> l, l- s TCD.
while e do s end lb:<e>{JMC l}<s>{JMP lb} l. lb - TCD, . l - TCD, {JMP lb}. . , s , do end. lb TCD. .. ≤0, l TCD ( .)
, . SPL
f()
begin
;
end
a:{ INI m} <s> {OPR 10}
a - ( TCD );
m - .
s - , begin and.
. SPL
main(x,y)
begin
int c;
read c;
c=x-y/c;
if c then return c
end
, .
main() x y .
n.
x (n+2)=-4. y -3. 1.
, x,y, c st[sp-4], st[sp-3], st[sp+1].
, .
TCD | ||
INI 1 | ||
OPR 1 | stdin (stdin→t) | |
STI 1 | c=t. | |
LDI -4 | x | |
LDL -3 | y t. x t -1 | |
LDI 1 | c t, x t -2, y - t -1 | |
OPR 6 | y c, t | |
OPR 4 | x-y/c. t | |
STI 1 | t | |
LDI 1 | c=x-y/c. c . , . | |
JMC 13 | ≤0, 13. - , .. 11 | |
LDI 1 | , .. t | |
OPR 9 | return. main(). - t | |
OPR 10 |
, TCD cmd TCD [300].
( ) ( ). , TCD .
i | TCD[i].cod | TCD[i].opd |
-4 | ||
-3 | ||
, , SPL.
12
body(), stat(), expr(), term(), fact(). gen()/.
:
int cgv=0, clv=0; //
int tc=0; // , TCD
int out=1 // out=1, . out=0, -
int gen(int co, int op)
{
if (tc>=300)
{
puts( TCD);
exit(1);
}
TCD[tc].cod=co;
TCD[tc].opd=op;
return tc + +;
}
return tc + +. TCD, .
body()
int body()
{
int st; //
exam(BEGINL);
clv=0;// .
while(lex = = INTL|| lex = = CONSTL)
if (lex = = CONSTL)
dconst();
else
dvarb();// clv
st = gen(INI, clv); // TCD
stml();
exam(ENDL);
gen(OPR, 10); //
return st;// .
}
body() gen() TCD .
stat()
void stat()
{
int t1, t2;
odc*p;
switch(lex)
{
case IDEN: p= findob((char*)lval); get();
exam(=); expr();
if(p→what = =1);
{
printf(%s- . \n,p→name);
exit(1)
}
gen (p->what == 2? STE: STI, p->val); break;
case READL:
get(); p = findob ((char *)lval); gen (OPR, 1);
if (p->what == 1)
{
printf ("%s \n", p->name);
exit(1);
}
gen (p->what == 2? STE: STI, p->val);
exam (IDEN); break;
case IFL:
get(); expr(); exam (THENL);
t1 = gen (JMC, 0); stml(); exam (ENDL);
TCD[t1].opd = tc; break;
case WHILEL:
get(); t1 = tc; expr();
exam (DOL); t2 = gen (JMC, 0); stml();
gen (JMP, t1); TCD[t2].opd = tc;
exam (ENDL); break;
case PRITL:
get(); expr(); gen (OPR, 2); break;
case RETRL:
get(); expr(); gen (OPR, 9); break;
default:
printf( lex=%i nst=%i \n, lex, nst);
}
return;
}
case IDEN TOB (char*) lval. , lval - . , TNM. int lval (char*,) findob(char*name) char*. odc*p. →what 1, , , . xit(1) . →what 2, . gen (ST, p->val).
gen (STI, p->val). , p->val . , c 1. c gen (STI, 1).
case READL , TCD
OPR 1 stdin, , . - .
case IFL (get()) expr() thenl. t1 tc TCD, gen (JMC,0)- 0 TCD. stml() TCD . , tc. tc , t1 TCD
TCD[t1].opd=tc.
case WHILEL. get() TCD, . , :
lb:<e>{JMC l}<s>{JMP lb} l.
t1=tc lb <e>.
t2=gen(JMC,0) - JMC0 TCD. <s>, stml(), (JMP,t1)- , <e> . case IFL, TCD[t2].opd=tc (JMC,0) (JMC,tc).
13
expr ()
void expr ()
{
int neg = (lex == ' - ');
if (lex == '+' || lex == '-')
get();
term();
if (neg)
gen (OPR, 8);
while (lex == '+' || lex == '-')
{
neg = (lex == ' - '? 4: 3);
get();
term();
gen (OPR, neg);
}
return;
}
expr () lex -, .. 1. OPR 8 .
g + - OPR 3 OPR 4.
term()
void term ()
{
int op;
fact();
while (lex == '*' || lex == '/' || lex == '%')
{
op = (lex == '*'? 5: (lex == '/'? 6: 7));
get();
fact();
gen (OPR, op);
}
return;
}
op 5 6, 7 . OPR 5 OPR 6, OPR 7.
fact()
void fact ()
{
char *nm;
int cp; //
odc *p;
fnd *p1;
switch (lex)
{
case IDEN: nm = (char *)lval; get();
if (lex == '(')
{
get();
cp = (lex == ')'? 0: fctl()); // FCTL
exam(')');
p1 = eval (nm, cp); // nm cp
gen (LIT, cp);//
cp = gen (CAL, p1->start); // TCD
if (!p1->isd)
p1->start = cp;/* , p1->start TCD */
}
else
{
p = findob (nm);
gen (p->what == 1? LIT: (p->what == 2? LDE: LDI), p->val);
}
break;
case '(': get(); expr(); exam(')');
break;
case NUMB: gen (LIT, lval); get();
break;
default: printf (" fact() lex=%i nst=%i \n", lex, nst);
exit(1);
}
return;
}
case IDEN. , , , .
.
, . , {LIT, lval},{LDE, lval} {LDI, lval } , , .
fctl()
int fctl ()
{
int cf = 1; // , .
expr();
while (lex == ',')
{
get();
expr();
cf++;
}
return cf;
}
fctl() , cf.
14
, TFN.
newob(). cons(), dvarb(), param(). newob() exam(IDEN) exam(NUMB) get().
cons()
void cons ()
{
char *nm = (char *)lval; //
int s;
exam (IDEN);
exam('=');
s = (lex == '-'? -1: 1);
if (lex == '-' || lex == '+')
get();
newob (nm, 1, s*lval); // .
exam (NUMB);
return;
}
dvarb()
void dvarb ()
{
do
{
get();
newob ((char *)lval, (out? 2: 3), (out? cgv++: ++clv));
exam (IDEN);
} while (lex == ',');
exam (';');
return;
}
out , . , odc what 2, val ( )- cgv+ +. - what 3, val - + +clv. , . int cgv=0 . st[0]. cgv 1 , st[1] ..
.
clv , , clv (++clv).
out , dfunc() out=0, out=1.
dfunc()
void dfunc ()
{
int cp; //
int st; //
char *nm = (char *)lval; //
get();
out = 0; // ,
cp = param(); //
st = body(); //
out = 1; // out.
ptol = pto; // ,
defin (nm, cp, st); //
return;
}
param ()
int param ()
{
odc *p;
int cp = 0; //
exam('(');
if (lex!= ')')
{
newob ((char *)lval, 3, ++cp);
exam (IDEN);
while (lex == ',')
{
get();
newob ((char *)lval, 3, ++cp);
exam (IDEN);
}
}
exam (')');
for (p = ptol; p < pto; p++)
p->val -= cp+3;
return cp;
}
ptol . ptol pto- . ( : ). for(), p→val +3. , f(x,y,z) . for x 1, y 2, z 3. for() x -5, y - -4,
z --3.
prog()
SPL , main(). SPL. , , ( TCD) . :
int adrnm; // main()
int cpnm; // main()
prog()
void prog ()
{
fnd *p;
while (lex!= EOF)
switch (lex)
{
case CONSTL: dconst(); break;
case INTL: dvarb(); break;
case IDEN: dfunc(); break;
default: printf ( prog lex=%i
nst=%i\n,lex, nst);
}
p = fmain();
adrnm = p->start;// main() TCD
cpnm = p->cpt;/ main()
return;
}
, fmain() .
, | ||
newob(char*nm, int wt, int vl) | cons(), dvarb(), param() | |
findob(char*nm) | stat(), fact | |
newfn(char*nm, int df, int cp, int ps) | eval(char*nm, int cp); define(char*nm, int cp, int ad) | |
findfn(char*nm) | eval(char*nm, int cp); defin(char*nm, int cp, int ad) | |
eval(char*nm, int cp) | fact() | |
defin(char*nm, int cp, int ad) | dfunc() | |
fmain() | prog() |
15
SPL-
:
int t; //st[t]- ;
int sp; //st[sp]- ;
int p; // , TCD.
main() get();, prog(); interp();. interp(); SPL - , TC D. : comman()- , TCD[p], - ;
operat(a)- OPR a;
push(a)- ;
reader()- (stdin→t).
interp()
void interp ()
{
int i;
t = -1; /* st[t] -1, push() st[+ +t]= st[0] */
puts(SPL- \n);
for (i = 0; i < cgv; i++)
push(0); /* ,
cqv ,
*/
if (cpnm)
{
printf ("%d>", cpnm);
fflush (stdin);
for (i = 0; i < cpnm; i++)
push (reader());
}/* cpnm main() ,
for() */
push (cpnm); /* main()*/
push(-2);/* =-2 */
push(-1);/* = -1 - st[t]*/
sp = t; /* t.
sp - */
p = adrnm; /* ( )
main() .
,
TCD* /
do
{
comman(); // TCD[p]
p++; //
} while (p >= 0);
if (p == -1)
printf ("%d\n", st[t]);/* <0 = = -1,
st[t]*/
return;
}
void comman ()
{
int a = TCD[p].opd; //
switch (TCD[p].cod)
{
case OPR: operat(a); break;
case LIT: push(a); break;//{LIT a}
case LDE: push(st[a]); break;//{LDE a}
case LDI: push(st[sp+a]); break;//{LDI a}
case STE: st[a] = st[t--]; break; /* , st[a] t, t */
case STI: st[sp+a] = st[t--]; break;
case CAL: push(p); push(sp);sp = t; p = a-1; break;/* p sp. sp=t. . -1. interp()
+ +. . , {CAL a }*/
case INI: for (i =0; i<a; i++)
push(0); /* . */
break;
case JMP: p = a-1;
break;/* TCD, */
case JMC: if (st[t--] <= 0)
p = a-1;/* ≤0, -1. , t , */
}
return;
}
void operat (int a)
{
int j = t-1;
switch (a)
{
case 1: printf ("1>");
fflush (stdin);
push (reader()); /* */
break;
case 2: printf ("%d\n", st[t--]); break;
case 3: st[j] += st[t--]; break; /* t=10, j=10-1=9 st[9]=st[9]+ st[10]. <