* basic parsing for bodies of C programs

git-svn-id: trunk@948 -
This commit is contained in:
florian 2005-08-27 12:58:09 +00:00
parent a02c5b9f45
commit d94fa751e0
5 changed files with 11638 additions and 10637 deletions

View File

@ -2,71 +2,77 @@ unit converu;
interface
const TYPEDEF = 257;
const DEFINE = 258;
const COLON = 259;
const SEMICOLON = 260;
const COMMA = 261;
const LKLAMMER = 262;
const RKLAMMER = 263;
const LECKKLAMMER = 264;
const RECKKLAMMER = 265;
const LGKLAMMER = 266;
const RGKLAMMER = 267;
const STRUCT = 268;
const UNION = 269;
const ENUM = 270;
const ID = 271;
const NUMBER = 272;
const CSTRING = 273;
const SHORT = 274;
const UNSIGNED = 275;
const LONG = 276;
const INT = 277;
const REAL = 278;
const _CHAR = 279;
const VOID = 280;
const _CONST = 281;
const _FAR = 282;
const _HUGE = 283;
const _NEAR = 284;
const _ASSIGN = 285;
const NEW_LINE = 286;
const SPACE_DEFINE = 287;
const EXTERN = 288;
const STDCALL = 289;
const CDECL = 290;
const CALLBACK = 291;
const PASCAL = 292;
const WINAPI = 293;
const APIENTRY = 294;
const WINGDIAPI = 295;
const SYS_TRAP = 296;
const _PACKED = 297;
const ELLIPSIS = 298;
const R_AND = 299;
const EQUAL = 300;
const UNEQUAL = 301;
const GT = 302;
const LT = 303;
const GTE = 304;
const LTE = 305;
const QUESTIONMARK = 306;
const _OR = 307;
const _AND = 308;
const _PLUS = 309;
const MINUS = 310;
const _SHR = 311;
const _SHL = 312;
const STAR = 313;
const _SLASH = 314;
const _NOT = 315;
const PSTAR = 316;
const P_AND = 317;
const POINT = 318;
const DEREF = 319;
const STICK = 320;
const SIGNED = 321;
const _WHILE = 257;
const _FOR = 258;
const _DO = 259;
const _GOTO = 260;
const _CONTINUE = 261;
const _BREAK = 262;
const TYPEDEF = 263;
const DEFINE = 264;
const COLON = 265;
const SEMICOLON = 266;
const COMMA = 267;
const LKLAMMER = 268;
const RKLAMMER = 269;
const LECKKLAMMER = 270;
const RECKKLAMMER = 271;
const LGKLAMMER = 272;
const RGKLAMMER = 273;
const STRUCT = 274;
const UNION = 275;
const ENUM = 276;
const ID = 277;
const NUMBER = 278;
const CSTRING = 279;
const SHORT = 280;
const UNSIGNED = 281;
const LONG = 282;
const INT = 283;
const REAL = 284;
const _CHAR = 285;
const VOID = 286;
const _CONST = 287;
const _FAR = 288;
const _HUGE = 289;
const _NEAR = 290;
const NEW_LINE = 291;
const SPACE_DEFINE = 292;
const EXTERN = 293;
const STDCALL = 294;
const CDECL = 295;
const CALLBACK = 296;
const PASCAL = 297;
const WINAPI = 298;
const APIENTRY = 299;
const WINGDIAPI = 300;
const SYS_TRAP = 301;
const _PACKED = 302;
const ELLIPSIS = 303;
const _ASSIGN = 304;
const R_AND = 305;
const EQUAL = 306;
const UNEQUAL = 307;
const GT = 308;
const LT = 309;
const GTE = 310;
const LTE = 311;
const QUESTIONMARK = 312;
const _OR = 313;
const _AND = 314;
const _PLUS = 315;
const MINUS = 316;
const _SHR = 317;
const _SHL = 318;
const STAR = 319;
const _SLASH = 320;
const _NOT = 321;
const PSTAR = 322;
const P_AND = 323;
const POINT = 324;
const DEREF = 325;
const STICK = 326;
const SIGNED = 327;
implementation

File diff suppressed because it is too large Load Diff

View File

@ -387,10 +387,15 @@ program h2pas;
write(outfile,')');
flush(outfile);
end;
else internalerror(2);
else
begin
writeln(ord(p^.typ));
internalerror(2);
end;
end;
end;
end;
procedure write_ifexpr(var outfile:text; p : presobject);
begin
@ -1144,8 +1149,42 @@ program h2pas;
end;
end;
procedure write_statement_block(var outfile:text; p : presobject);
begin
writeln(outfile,aktspace,'begin');
while assigned(p) do
begin
shift(2);
if assigned(p^.p1) then
begin
case p^.p1^.typ of
t_whilenode:
begin
write(outfile,aktspace,'while ');
write_expr(outfile,p^.p1^.p1);
writeln(outfile,' do');
shift(2);
write_statement_block(outfile,p^.p1^.p2);
popshift;
end;
else
begin
write(outfile,aktspace);
write_expr(outfile,p^.p1);
writeln(outfile,';');
end;
end;
end;
p:=p^.next;
popshift;
end;
writeln(outfile,aktspace,'end;');
end;
%}
%token _WHILE _FOR _DO _GOTO _CONTINUE _BREAK
%token TYPEDEF DEFINE
%token COLON SEMICOLON COMMA
%token LKLAMMER RKLAMMER LECKKLAMMER RECKKLAMMER
@ -1155,10 +1194,11 @@ program h2pas;
%token SHORT UNSIGNED LONG INT REAL _CHAR
%token VOID _CONST
%token _FAR _HUGE _NEAR
%token _ASSIGN NEW_LINE SPACE_DEFINE
%token NEW_LINE SPACE_DEFINE
%token EXTERN STDCALL CDECL CALLBACK PASCAL WINAPI APIENTRY WINGDIAPI SYS_TRAP
%token _PACKED
%token ELLIPSIS
%right _ASSIGN
%right R_AND
%left EQUAL UNEQUAL GT LT GTE LTE
%left QUESTIONMARK COLON
@ -1233,8 +1273,211 @@ systrap_specifier:
| { $$:=nil; }
;
statement :
expr SEMICOLON { $$:=$1; } |
_WHILE LKLAMMER expr RKLAMMER statement_list { $$:=new(presobject,init_two(t_whilenode,$3,$5)); }
;
statement_list : statement statement_list
{
$$:=new(presobject,init_one(t_statement_list,$1));
$$^.next:=$2;
} |
statement
{
$$:=new(presobject,init_one(t_statement_list,$1));
} |
SEMICOLON
{
$$:=new(presobject,init_one(t_statement_list,nil));
} |
{
$$:=new(presobject,init_one(t_statement_list,nil));
}
;
statement_block :
LGKLAMMER statement_list RGKLAMMER { $$:=$2; }
;
declaration :
dec_specifier type_specifier dec_modifier declarator_list systrap_specifier SEMICOLON
dec_specifier type_specifier dec_modifier declarator_list statement_block
{
IsExtern:=false;
(* by default we must pop the args pushed on stack *)
no_pop:=false;
if (assigned($4)and assigned($4^.p1)and assigned($4^.p1^.p1))
and ($4^.p1^.p1^.typ=t_procdef) then
begin
repeat
If UseLib then
IsExtern:=true
else
IsExtern:=assigned($1)and($1^.str='extern');
no_pop:=assigned($3) and ($3^.str='no_pop');
if (block_type<>bt_func) and not(createdynlib) then
begin
writeln(outfile);
block_type:=bt_func;
end;
(* dyn. procedures must be put into a var block *)
if createdynlib then
begin
if (block_type<>bt_var) then
begin
if not(compactmode) then
writeln(outfile);
writeln(outfile,aktspace,'var');
block_type:=bt_var;
end;
shift(2);
end;
if not CompactMode then
begin
write(outfile,aktspace);
if not IsExtern then
write(implemfile,aktspace);
end;
(* distinguish between procedure and function *)
if assigned($2) then
if ($2^.typ=t_void) and ($4^.p1^.p1^.p1=nil) then
begin
if createdynlib then
begin
write(outfile,$4^.p1^.p2^.p,' : procedure');
end
else
begin
shift(10);
write(outfile,'procedure ',$4^.p1^.p2^.p);
end;
if assigned($4^.p1^.p1^.p2) then
write_args(outfile,$4^.p1^.p1^.p2);
if createdynlib then
begin
loaddynlibproc.add('pointer('+$4^.p1^.p2^.p+'):=GetProcAddress(hlib,'''+$4^.p1^.p2^.p+''');');
freedynlibproc.add($4^.p1^.p2^.p+':=nil;');
end
else if not IsExtern then
begin
write(implemfile,'procedure ',$4^.p1^.p2^.p);
if assigned($4^.p1^.p1^.p2) then
write_args(implemfile,$4^.p1^.p1^.p2);
end;
end
else
begin
if createdynlib then
begin
write(outfile,$4^.p1^.p2^.p,' : function');
end
else
begin
shift(9);
write(outfile,'function ',$4^.p1^.p2^.p);
end;
if assigned($4^.p1^.p1^.p2) then
write_args(outfile,$4^.p1^.p1^.p2);
write(outfile,':');
write_p_a_def(outfile,$4^.p1^.p1^.p1,$2);
if createdynlib then
begin
loaddynlibproc.add('pointer('+$4^.p1^.p2^.p+'):=GetProcAddress(hlib,'''+$4^.p1^.p2^.p+''');');
freedynlibproc.add($4^.p1^.p2^.p+':=nil;');
end
else if not IsExtern then
begin
write(implemfile,'function ',$4^.p1^.p2^.p);
if assigned($4^.p1^.p1^.p2) then
write_args(implemfile,$4^.p1^.p1^.p2);
write(implemfile,':');
write_p_a_def(implemfile,$4^.p1^.p1^.p1,$2);
end;
end;
(* No CDECL in interface for Uselib *)
if IsExtern and (not no_pop) then
write(outfile,';cdecl');
popshift;
if createdynlib then
begin
writeln(outfile,';');
end
else if UseLib then
begin
if IsExtern then
begin
write (outfile,';external');
If UseName then
Write(outfile,' External_library name ''',$4^.p1^.p2^.p,'''');
end;
writeln(outfile,';');
end
else
begin
writeln(outfile,';');
if not IsExtern then
begin
writeln(implemfile,';');
shift(2);
if $5^.typ=t_statement_list then
write_statement_block(implemfile,$5);
popshift;
end;
end;
IsExtern:=false;
if not(compactmode) and not(createdynlib) then
writeln(outfile);
until not NeedEllipsisOverload;
end
else (* $4^.p1^.p1^.typ=t_procdef *)
if assigned($4)and assigned($4^.p1) then
begin
shift(2);
if block_type<>bt_var then
begin
if not(compactmode) then
writeln(outfile);
writeln(outfile,aktspace,'var');
end;
block_type:=bt_var;
shift(3);
IsExtern:=assigned($1)and($1^.str='extern');
(* walk through all declarations *)
hp:=$4;
while assigned(hp) and assigned(hp^.p1) do
begin
(* write new var name *)
if assigned(hp^.p1^.p2) and assigned(hp^.p1^.p2^.p) then
write(outfile,aktspace,hp^.p1^.p2^.p);
write(outfile,' : ');
shift(2);
(* write its type *)
write_p_a_def(outfile,hp^.p1^.p1,$2);
if assigned(hp^.p1^.p2)and assigned(hp^.p1^.p2^.p)then
begin
if isExtern then
write(outfile,';cvar;external')
else
write(outfile,';cvar;public');
end;
writeln(outfile,';');
popshift;
hp:=hp^.p2;
end;
popshift;
popshift;
end;
if assigned($1)then dispose($1,done);
if assigned($2)then dispose($2,done);
if assigned($4)then dispose($4,done);
}
| dec_specifier type_specifier dec_modifier declarator_list systrap_specifier SEMICOLON
{
IsExtern:=false;
(* by default we must pop the args pushed on stack *)
@ -2251,32 +2494,33 @@ abstract_declarator :
}
;
expr :
shift_expr
{$$:=$1;}
expr : shift_expr
{ $$:=$1; }
;
shift_expr :
expr EQUAL expr
{ $$:=new(presobject,init_bop(' = ',$1,$3));}
expr _ASSIGN expr
{ $$:=new(presobject,init_bop(':=',$1,$3)); }
| expr EQUAL expr
{ $$:=new(presobject,init_bop('=',$1,$3));}
| expr UNEQUAL expr
{ $$:=new(presobject,init_bop(' <> ',$1,$3));}
{ $$:=new(presobject,init_bop('<>',$1,$3));}
| expr GT expr
{ $$:=new(presobject,init_bop(' > ',$1,$3));}
{ $$:=new(presobject,init_bop('>',$1,$3));}
| expr GTE expr
{ $$:=new(presobject,init_bop(' >= ',$1,$3));}
{ $$:=new(presobject,init_bop('>=',$1,$3));}
| expr LT expr
{ $$:=new(presobject,init_bop(' < ',$1,$3));}
{ $$:=new(presobject,init_bop('<',$1,$3));}
| expr LTE expr
{ $$:=new(presobject,init_bop(' <= ',$1,$3));}
{ $$:=new(presobject,init_bop('<=',$1,$3));}
| expr _PLUS expr
{ $$:=new(presobject,init_bop(' + ',$1,$3));}
{ $$:=new(presobject,init_bop('+',$1,$3));}
| expr MINUS expr
{ $$:=new(presobject,init_bop(' - ',$1,$3));}
{ $$:=new(presobject,init_bop('-',$1,$3));}
| expr STAR expr
{ $$:=new(presobject,init_bop(' * ',$1,$3));}
{ $$:=new(presobject,init_bop('*',$1,$3));}
| expr _SLASH expr
{ $$:=new(presobject,init_bop(' / ',$1,$3));}
{ $$:=new(presobject,init_bop('/',$1,$3));}
| expr _OR expr
{ $$:=new(presobject,init_bop(' or ',$1,$3));}
| expr _AND expr
@ -2288,7 +2532,8 @@ shift_expr :
| expr _SHR expr
{ $$:=new(presobject,init_bop(' shr ',$1,$3));}
| expr QUESTIONMARK colon_expr
{ $3^.p1:=$1;
{
$3^.p1:=$1;
$$:=$3;
inc(if_nb);
$$^.p:=strpnew('if_local'+str(if_nb));

View File

@ -29,7 +29,7 @@ unit scan;
lexlib,yacclib;
const
version = '0.99.16';
version = '1.0.0';
type
Char=system.char;
@ -108,8 +108,18 @@ unit scan;
p2 the typecast expr }
t_size_specifier,
{ p1 expr for size }
t_default_value
t_default_value,
{ p1 expr for value }
t_statement_list,
{ p1 is the statement
next is next if it exist }
t_whilenode,
t_fornode,
t_dowhilenode,
t_switchnode,
t_gotonode,
t_continuenode,
t_breaknode
);
const
@ -141,7 +151,15 @@ const
't_funcname',
't_typespec',
't_size_specifier',
't_default_value'
't_default_value',
't_statement_list',
't_whilenode',
't_fornode',
't_dowhilenode',
't_switchnode',
't_gotonode',
't_continuenode',
't_breaknode'
);
type
@ -782,6 +800,7 @@ D [0-9]
"near" return(_NEAR);
"HUGE" return(_HUGE);
"huge" return(_HUGE);
"while" return(_WHILE);
[A-Za-z_][A-Za-z0-9_]* begin
if in_space_define=1 then
in_space_define:=2;

File diff suppressed because it is too large Load Diff