views:

106

answers:

3

I think my program should be able to recognize the following as a function declaration

int fn(int i) { int n; return; }

but it doesn't.

Here's the relevant part of my yacc file

program : declaration_list ; 

declaration_list : declaration_list declaration | declaration ;

declaration : var_declaration 
      | fun_declaration 
      | '$' { printTable();};

var_declaration : type_specifier ID ';' {$2->value = 0; $2->arraysize = 0;};
                | type_specifier ID '[' NUM ']' ';' {$2->arraysize = $4;printf("Array size is %d", $2->arraysize);} ;

type_specifier : INT | VOID ;

fun_declaration : type_specifier ID '(' params ')' compound_stmt {printf("function declaration\n"); printf("Parameters: \n", $2->args); } ;


params : param_list | VOID ;

param_list : param_list ',' param
           | param ;

param : type_specifier ID | type_specifier ID '[' ']' ;

compound_stmt : '{' local_declarations statement_list '}' {printf("exiting scope\n"); } ;

local_declarations : local_declarations var_declaration
                   | /* empty */ ;

statement_list : statement_list statement
               | /* empty */ ;

statement : expression_stmt
          | compound_stmt
          | selection_stmt
          | iteration_stmt
          | return_stmt ;

expression_stmt : expression ';'
                | ';' ;

selection_stmt : IF '(' expression ')' statement
               | IF '(' expression ')' statement ELSE statement ;

iteration_stmt : WHILE '(' expression ')' statement ;

return_stmt : RETURN ';' | RETURN expression ';' ;

Why does it not recognize it?

A: 

Just looked at the line where you have

local_declarations : local_declarations var_declaration
                   | /* empty */ ;

That line looks troublesome to me, since you have it like a recursive statement...

Hope this gives you the hint, Best regards, Tom.

tommieb75
A: 

I think you need something like:

declaration : type_specifier ID ';' {$2->value = 0; $2->arraysize = 0;};
            | type_specifier ID '[' NUM ']' ';' {$2->arraysize = $4;printf("Array size is %d", $2->arraysize);} ;
            | type_specifier ID '(' params ')' compound_stmt {printf("function declaration\n"); printf("Parameters: \n", $2->args); } ;

            | '$' { printTable();};

type_specifier : INT | VOID ;

Richard Pennington
+1  A: 

This isn't an answer to your question but a suggestion for debugging.

After each of the rules, add a printf statement which tells you that the rule has been matched. Take a look at my answer here for hints. Then run your input through the grammar and see what it is doing.

Another hint, for asking questions, is to try to reduce your problem to the simplest case which reproduces the error. In the case of the above grammar, strip out all of the rules which you don't expect to match this particular example before posting it. Also, post a complete program, with the %token declarations, so people can compile it and try it out for themselves. Even better is to post the lexer too.

Kinopiko