3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-19 10:29:30 +01:00

CGrammar: Optimize postfix_expression rule and fix function definitions

This commit is contained in:
Pragmatic Software 2014-06-15 03:57:27 +00:00
parent 2dba87f453
commit 9389edd2df
3 changed files with 34 additions and 38 deletions

View File

@ -13,7 +13,7 @@ use warnings;
# These are set automatically by the build/commit script
use constant {
BUILD_NAME => "PBot",
BUILD_REVISION => 641,
BUILD_REVISION => 642,
BUILD_DATE => "2014-06-14",
};

View File

@ -171,8 +171,6 @@ print "--- precode: [$precode]\n" if $debug;
my $lang = 'C89';
if($lang eq 'C89' or $lang eq 'C99' or $lang eq 'C11' or $lang eq 'C++') {
my $has_main = 0;
my $prelude = '';
while($precode =~ s/^\s*(#.*\n{1,2})//g) {
$prelude .= $1;
@ -393,9 +391,12 @@ $output = `./c2eng.pl code2eng.c` if not defined $output;
if(not $has_function and not $has_main) {
$output =~ s/Let .main. be a function taking no parameters and returning int.\s*To perform the function.\s*(return 0.)?//i;
$output =~ s/\s*Return 0.\s*End of function .main..\s*//;
$output =~ s/\s*Return 0.$//;
$output =~ s/\s*Do nothing.\s*$//;
$output =~ s/^\s*(.)/\U$1/;
$output =~ s/\.\s+(\S)/. \U$1/g;
} elsif($has_function and not $has_main) {
$output =~ s/\s*Let `main` be a function taking no parameters and returning int.\s*To perform the function, return 0.//;
}
$output =~ s/\s+/ /;

View File

@ -146,8 +146,8 @@ external_declaration:
declaration
function_definition:
<skip: '\s*'> declaration_specifiers(?) declarator[context => 'function_definition']
'(' parameter_type_list(?) ')' '{' declaration_list(?) statement_list(?) '}'
declaration_specifiers(?) declarator[context => 'function_definition'] '(' parameter_type_list(?) ')'
'{' declaration_list(?) statement_list(?) '}'
{
my $declaration_specifiers = join('', @{$item{'declaration_specifiers(?)'}});
my $parameter_list = join('', @{$item{'parameter_type_list(?)'}});
@ -157,12 +157,11 @@ function_definition:
my $return_type = $item{declarator};
my $name = $item{declarator};
$name =~ s/^.*?`/`/;
$return_type =~ s/`.*`//;
$name =~ s/`[^`]+$/`/;
$return_type =~ s/`.*`\|?//;
if ($return_type =~ /\w/ ) {
$return_type .= "to a ";
$return_type .= $declaration_specifiers;
$return_type .= " $declaration_specifiers";
} else {
$return_type = $declaration_specifiers;
}
@ -311,7 +310,7 @@ iteration_statement:
}
}
| 'do' statement[context => 'do loop'] 'while' '(' expression ')' ';'
{ $return = "Do the following:^L $item{statement}\nDo this as long as $item{expression}.\n"; }
{ $return = "Do the following:^L $item{statement}Do this as long as $item{expression}.\n"; }
for_initialization:
expression[context => 'for loop']
@ -838,24 +837,13 @@ unary_expression:
|'sizeof' '(' type_name ')'
{ $return = "the size of the datatype $item{type_name}"; }
postfix_expression:
primary_expression[context => $arg{context}] '(' argument_expression_list(?) ')' # function call
postfix_function_call:
'(' argument_expression_list(?) ')'
{
push @basics, $basic;
$basic = $item{primary_expression};
if(not defined $arg{context} or $arg{context} eq 'assignment_expression') {
$return = "the result of ";
$return = "the result of the function $arg{primary_expression}";
} else {
$return = "Perform ";
}
# is this function call involving a pointer to a function?
if ($basic =~ /parenthetical/) {
$return .= "the function pointed by $basic";
} else {
$return =~ s/Perform/Call/;
$return .= "the function $basic";
$return = "Call the function $arg{primary_expression} ";
}
# To discriminate between macros and functions.
@ -872,16 +860,20 @@ postfix_expression:
}
1;
}
| primary_expression[context => $arg{context}]
| {""}
postfix_expression:
primary_expression[context => $arg{context}] postfix_function_call[primary_expression => $item[1], context => $arg{context}]
{
# must be global. use stack to prevent disasters.
# Todo: this is just a Bad Idea, TM. $return needs to be turned to an hash with the
# arguments doing the right thing and then the last action assembles the sucker.
push @basics, $basic;
$basic = $item{primary_expression};
$return = $item{primary_expression};
}
if($item{postfix_function_call}) {
$return = $item{postfix_function_call};
} else {
$return = $item{primary_expression};
}
}
# array reference and plain expression
( '[' expression[context => 'array_address'] ']'
{ $return = $item{expression}; }
@ -957,7 +949,6 @@ postfix_expression:
$basic = pop @basics;
1;
}
# having done the simplest cases, we go to the catch all for left recursions.
| primary_expression postfix_suffix(s)
{
@ -978,18 +969,22 @@ argument_expression_list:
{
my @arg_exp_list = @{$item[1]};
my $last = '';
if ($#arg_exp_list > 1) {
if (@arg_exp_list > 2) {
$last = pop @arg_exp_list;
$return = 's ' . join(', ', @arg_exp_list) . ", and $last";
} elsif ( $#arg_exp_list == 1 ) {
} elsif (@arg_exp_list == 2 ) {
$return = "s $arg_exp_list[0] and $arg_exp_list[1]";
} else {
$return = " $arg_exp_list[0]";
} else {
if ($arg_exp_list[0]) {
$return = " $arg_exp_list[0]";
} else {
$return = '';
}
}
}
}
narrow_closure:
';' | ',' | '->'
';' | ',' | '->'
primary_expression:
'(' expression ')' (...narrow_closure)(?)