The following compiler uses stack as temporary storage for symbols.
Converted grammar allows choice
the appropriate rule by the order of appearance.
c.def file:
symb ;
numb ;
name ;
type ;
var ;
array ;
fn ;
lsb "[" 0 0;
rsb "]" 0 0;
lcb "(" 0 0;
rcb ")" 0 0;
assign ":=" 0 0;
plus "+" 0 0;
minus "-" 0 1;
star "*" 0 2;
slash "/" 0 3;
pct "%" 0 4;
lt "<" 0 0;
le "<=" 0 1;
eq "=" 0 2;
ne "!=" 0 3;
ge ">=" 0 4;
gt ">" 0 5;
comma "," 0 0;
semi ";" 0 0;
is 0 0;
begin 0 0;
if 0 0;
then 0 0;
while 0 0;
do 0 0;
inline 0 0;
return 0 0;
end 0 0;
char 1 1;
byte 1 1;
word 1 2.
Program : 10 Declarations Main Stmts end
| 10 Main Stmts end
;
Declarations : 0 Declarations Declaration
| 0 Declaration
;
Declaration : 20 TypeName semi
| 30 TypeName lsb numb rsb semi
| 10 Header Stmts end
;
Header : 40 TypeName lcb Args TypeName rcb is
| 50 TypeName lcb TypeName rcb is
| 0 TypeName lcb rcb is
;
Args : 0 Args Arg
| 0 Arg
;
Arg : 60 TypeName comma
;
TypeName : 70 type name
;
Main : 80 begin
;
Stmts : 90 Stmts Stmt
| 90 Stmt
;
Stmt : 100 IfBlk
| 100 WhileBlk
| 100 Inlines
| 110 Ret
| 100 Local
| 100 Assign
| 100 PCall
;
IfBlk : 120 IfHdr Stmts end
;
IfHdr : 130 if Comp symb then
| 130 if Comp numb then
| 140 if Comp Ref then
| 150 if Comp Call then
| 150 if Comp Cast then
| 150 if Comp Expr then
;
WhileBlk : 160 WhileHdr Stmts end
;
WhileHdr : 130 Loop Comp symb do
| 130 Loop Comp numb do
| 140 Loop Comp Ref do
| 150 Loop Comp Call do
| 150 Loop Comp Cast do
| 150 Loop Comp Expr do
;
Loop : 170 while
;
Inlines : 0 Opcodes semi
;
Opcodes : 180 Opcodes comma numb
| 190 inline numb
;
Ret : 200 return symb semi
| 200 return numb semi
| 210 return Ref semi
| 220 return Call semi
| 220 return Cast semi
| 220 return Expr semi
;
Local : 230 TypeName assign symb semi
| 230 TypeName assign numb semi
| 240 TypeName assign Ref semi
| 250 TypeName assign Call semi
| 250 TypeName assign Cast semi
| 250 TypeName assign Expr semi
;
Assign : 260 Ref assign symb semi
| 260 Ref assign numb semi
| 270 Ref assign Ref semi
| 280 Ref assign Call semi
| 280 Ref assign Cast semi
| 280 Ref assign Expr semi
;
PCall : 0 Call semi
;
Comp : 290 symb RelOp
| 290 numb RelOp
| 300 Ref RelOp
| 310 Call RelOp
| 310 Cast RelOp
| 310 Expr RelOp
;
Left : 290 numb Op
| 300 Ref Op
| 310 Call Op
| 310 Cast Op
| 310 Expr Op
| 310 Value Op
;
Ref : 0 var
| 320 array lsb numb rsb
| 330 array lsb Ref rsb
| 340 array lsb Call rsb
| 340 array lsb Cast rsb
| 340 array lsb Expr rsb
;
Call : 350 Fn2 lcb Params symb rcb
| 350 Fn2 lcb Params numb rcb
| 360 Fn2 lcb Params Ref rcb
| 370 Fn2 lcb Params Call rcb
| 370 Fn2 lcb Params Cast rcb
| 370 Fn2 lcb Params Expr rcb
| 380 Fn2 lcb symb rcb
| 380 Fn2 lcb numb rcb
| 390 Fn2 lcb Ref rcb
| 370 Fn2 lcb Call rcb
| 370 Fn2 lcb Cast rcb
| 370 Fn2 lcb Expr rcb
| 400 Fn2 lcb rcb
;
Params : 0 Params Param
| 0 Param
;
Param : 410 symb comma
| 410 numb comma
| 420 Ref comma
| 430 Call comma
| 430 Cast comma
| 430 Expr comma
;
Fn2 : 440 fn
;
Cast : 450 type lcb symb rcb
| 450 type lcb numb rcb
| 460 type lcb Ref rcb
| 0 type lcb Call rcb
| 0 type lcb Expr rcb
;
Expr : 470 Left numb
| 480 Left Ref
| 490 Left Call
| 490 Left Cast
| 490 Left Value
;
Value : 0 lcb Expr rcb
;
RelOp : 0 lt
| 0 le
| 0 eq
| 0 ne
| 0 ge
| 0 gt
;
Op : 0 plus
| 0 minus
| 0 star
| 0 slash
| 0 pct
.
c.prg file:
char Text [16384];
word pText;
word nText;
word nLine;
byte Code [16384];
word nCode;
word hFile;
char Heap [ 2048];
word nHeap;
word Jx [ 6];
word nData;
word Name [ 256];
word Cls [ 256];
word Sub [ 256];
word Type [ 256];
word Size [ 256];
word Ofs [ 256];
word nName;
word Sym [ 96];
word nSym;
word Left [ 192];
word Id [ 192];
word pRight [ 192];
word Len [ 192];
word nLeft;
word Right [ 640];
word pLeft [ 640];
word nRight;
word Stk [ 32];
word Val [ 32];
word Ptr [ 32];
word Frame [ 32];
word nStk;
char Buff [ 32];
word open() is
inline 0xB4, 0x3D; // mov AH, 3DH
inline 0xB0, 0x00; // mov AL, 0
inline 0xBA, 0x4A, 0xC1; // mov DX, @@DATA+Ofs(Heap[64])
inline 0xCD, 0x21; // int 21H
end
word create() is
inline 0xB4, 0x3C; // mov AH, 3CH
inline 0xB9, 0x00, 0x00; // mov CX, 0
inline 0xBA, 0x4A, 0xC1; // mov DX, @@DATA+Ofs(Heap[64])
inline 0xCD, 0x21; // int 21H
end
word read() is
inline 0xB4, 0x3F; // mov AH, 3FH
inline 0x8B, 0x1E, 0x08, 0xC1; // mov BX, word [@@DATA+Ofs(hFile)]
inline 0xB9, 0x00, 0x40; // mov CX, 16384
inline 0xBA, 0x00, 0x41; // mov DX, @@DATA+Ofs(Text)
inline 0xCD, 0x21; // int 21H
end
word write() is
inline 0xB4, 0x40; // mov AH, 40H
inline 0x8B, 0x1E, 0x08, 0xC1; // mov BX, word [@@DATA+Ofs(hFile)]
inline 0x8B, 0x0E, 0x06, 0xC1; // mov CX, word [@@DATA+Ofs(nCode)]
inline 0xBA, 0x06, 0x81; // mov DX, @@DATA+Ofs(Code)
inline 0xCD, 0x21; // int 21H
end
word close() is
inline 0xB4, 0x3E; // mov AH, 3EH
inline 0x8B, 0x1E, 0x08, 0xC1; // mov BX, word [@@DATA+Ofs(hFile)]
inline 0xCD, 0x21; // int 21H
end
char putc(char C) is
char C1:=C;
inline 0x92; // xchg DX, AX
inline 0xB4, 0x02; // mov AH, 2
inline 0xCD, 0x21; // int 21H
end
word halt() is
inline 0xB8, 0x00, 0x4C; // mov AX, 4C00H
inline 0xCD, 0x21; // int 21H
end
word Init() is
Heap [ 0]:='0';
Heap [ 1]:='1';
Heap [ 2]:='2';
Heap [ 3]:='3';
Heap [ 4]:='4';
Heap [ 5]:='5';
Heap [ 6]:='6';
Heap [ 7]:='7';
Heap [ 8]:='8';
Heap [ 9]:='9';
Heap [ 10]:='A';
Heap [ 11]:='B';
Heap [ 12]:='C';
Heap [ 13]:='D';
Heap [ 14]:='E';
Heap [ 15]:='F';
Heap [ 16]:='#';
Heap [ 17]:= char(0);
Heap [ 64]:='c';
Heap [ 65]:='.';
Heap [ 66]:='d'; // p
Heap [ 67]:='e'; // r
Heap [ 68]:='f'; // g
Heap [ 69]:= char(0);
nHeap := 70;
Sym [ 1]:= 16; // #
nSym := 2;
Jx [ 0]:= 0x72;
Jx [ 1]:= 0x76;
Jx [ 2]:= 0x74;
Jx [ 3]:= 0x75;
Jx [ 4]:= 0x73;
Jx [ 5]:= 0x77;
end
word Stop() is
nStk:=0;
while nLine!=0 do
Stk[nStk]:=nLine%10;
nStk :=nStk+1;
nLine :=nLine/10;
end
while nStk !=0 do
nStk :=nStk-1;
putc(char(Stk[nStk]+48));
end
close();
halt ();
end
word val () is
word E:=10;
word J:= 0;
if Buff[0]='0' then
if Buff[1]='x' then
E:=16;
J:= 2;
end
end
word N:=0;
while Buff[J]!=char(0) do
word K:=0;
while Heap[K]!=Buff[J] do
if K=E then
Stop();
end
K:=K+1;
end
N:=E*N;
N:=N+K;
J:=J+1;
end
return N;
end
word Copy() is
word pHeap:=nHeap;
word pBuff:=0;
while Buff[pBuff]!=char(0) do
Heap[nHeap]:= Buff[pBuff];
nHeap :=nHeap+1;
pBuff :=pBuff+1;
end
Heap[nHeap]:=char(0);
nHeap :=nHeap+1;
return pHeap;
end
word Comp(word pHeap) is
word pBuff:=0;
while Buff[pBuff]=Heap[pHeap] do
if Buff[pBuff]=char(0) then
return 0;
end
pHeap:=pHeap+1;
pBuff:=pBuff+1;
end
return 1;
end
char Look() is
if pText>=nText then
pText:=0;
nText:=read();
if pText>=nText then
return char(0);
end
end
return Text[pText];
end
char Read() is
char C:=Look();
pText :=pText+1;
return C;
end
word isalpha (char C) is
if 'A'<=C then
if C<='Z' then
return 0;
end
end
if 'a'<=C then
if C<='z' then
return 0;
end
end
return 1;
end
word isnumber(char C) is
if '0'<=C then
if C<='9' then
return 0;
end
end
return 1;
end
word isalnum (char C) is
if isalpha (C)=0 then
return 0;
end
if isnumber(C)=0 then
return 0;
end
return 1;
end
word Digraph(char C1, char C2) is
if Buff[0]=C1 then
if Look()=C2 then
Buff[1]:=Read();
Buff[2]:=char(0);
end
end
end
char Scan() is
word pBuff:=0;
while pBuff =0 do
word sFlag:=0;
while sFlag =0 do
if Look()!=char( 9) then
if Look()!=char(10) then
if Look()!=char(13) then
if Look()!=char(32) then
sFlag:=1;
end
end
end
end
if sFlag=0 then
if Read()=char(10) then
nLine:=nLine+1;
end
end
end
//if pBuff=0 then
while isalnum(Look())=0 do
Buff[pBuff]:= Read();
pBuff :=pBuff+1;
end
//end
if pBuff=0 then
Buff[pBuff]:= Read();
pBuff :=pBuff+1;
end
if Buff[0]=''' then
Buff[pBuff]:=Read(); // char
pBuff :=pBuff+1;
Buff[pBuff]:=Read(); // '
pBuff :=pBuff+1;
end
Buff[pBuff] :=char(0);
Digraph('<', '=');
Digraph('!', '=');
Digraph('>', '=');
Digraph(':', '=');
if Buff[0]='/' then
if Look()='/' then
while Look()!=char(10) do
if Read()=char( 0) then
Stop();
end
end
pBuff:=0;
end
end
end
end
word pSymb;
word pProg;
word L;
word V;
word Alter() is
L:=1;
word pName:=0;
while pName =3 then
Emi1(0x93); // xchg BX, AX
Emi1(0x33); // xor DX, DX
Emi1(0xD2);
Emi1(0xF7); // div BX
Emi1(0xF3);
end
if Op=4 then
Emi1(0x92); // xchg DX, AX
end
end
word Cond() is
Pop ();
Emi1(0x3B); // cmp BX, AX
Emi1(0xD8);
Emi1(Jx[Val[nStk+1]]);// jxx Ofs
Emi1(0x03);
Ptr[nStk]:= Val[nStk];
Val[nStk]:=nCode;
Emi1(0xE9); // jmp ?
nCode :=nCode+2;
lFlag :=0;
end
word Shl () is
if Size[Type[Val[nStk]]]!=1 then
Emi1(0xD1); // shl AX, 1
Emi1(0xE0);
end
end
word Save(word I) is
if Cls[I]=3 then
Pop ();
end
byte C:=0x89; // mov [(BX+)Ofs], AX
if Size[Type[I]]=1 then
C:=0x88; // mov [(BX+)Ofs], AL
end
Move(I, C);
end
word pParm;
word Pass() is
if pParm>=nName then
Stop();
end
if Sub[pParm]!=1 then
Stop();
end
Save(pParm);
pParm:=pParm+1;
lFlag:=0;
end
word Call() is
if pParm=Len[I] then
word J:=nStk-Len[I];
word K:=pRight[I];
while Stk[J]=Right[K] do
if Stk[J]=0 then
return I;
end
J:=J+1;
K:=K+1;
end
end
I:=I+1;
end
return I;
end
word Compile() is
Heap [ 66]:='p';
Heap [ 67]:='r';
Heap [ 68]:='g';
hFile := open();
pText := 0;
nText := 0;
nLine := 1;
lFlag := 0;
rFlag := 0;
nCode := 0;
nData :=16640;
Emi1(0xE9); // jmp ?
Emi2(0x00);
Stk [0] := 1; // #
nStk := 0;
while Stk[0]!=pProg do
Scan ();
Alter();
if nStk>=32 then
Stop();
end
Stk [nStk]:=L;
Val [nStk]:=V;
nStk :=nStk+1;
word I:=CheckTop();
while I< nLeft do
nStk :=nStk-Len[I];
Stk[nStk]:=Left[I];
Action(Id[I]);
nStk :=nStk+1;
I:=CheckTop();
end
end
close();
Heap [ 66]:='c';
Heap [ 67]:='o';
Heap [ 68]:='m';
hFile:=create();
write();
close();
end
begin
Init();
LoadGrammar();
Compile();
end