Pedro
Pedro

Reputation: 331

Recognizing function call pattern with Flex/Lex

I'm trying to write a Cminus (C-subset) compiler, but my professor demands that we are able to handle input() and output() functions as system calls (on the last semester we implemented a RISC CPU that can handle those instructions).

For the input() part, I managed to get it right on the first try (just do a pattern that matches "input()"), but the problem comes with output(). Since this function is supposed to take an array or a variable as an argument, I would assume that on the Lex patterns I need to have something like this (referencing what I read here):

digito          [0-9]
numero          {digito}+
letra           [a-zA-Z]
identificador   {letra}+({letra}|{digito})*
input           "input()"
outputStart     "output("
outputSimple    {identificador}
outputComplex   {identificador}"["identificador"]"
outputEnd       ")"
output          {outputStart} ({outputSimple} | {outputComplex}){outputEnd}

But I have the following definition on my grammar:

type: INT | VOID;
fun_decl: type ID LPAREN params RPAREN comp_decl;

where ID is a token given from Lex to Bison when it matches a string to identificador

My problem is that only fun_decl is being matched, but I digress.

To summarize, how do I match output(var) or output(array[i]) to a pattern? Is it even possible?

Edit1: After reading the response from @rici I managed to come up with this code for the productions, moving everything away from Lex/Flex, dealing only with Bison-YACC (rest of the code ommited for clarity):

ativacao    : id LPAREN args RPAREN
                {   
                    if(strcmp($1->attr.name, "output") == 0)
                    {
                        /*code for output system call*/
                    }
                    else if(strcmp($1->attr.name, "input") == 0)
                    {
                        /*code for input system call*/
                    } else{
                        /*code for other function activations*/
                    }
                }
            ;

Upvotes: 0

Views: 1570

Answers (2)

rici
rici

Reputation: 241721

Given that you have a production to recognize function declarations:

fun_decl: type ID LPAREN params RPAREN comp_decl;

It seems reasonable that you would have a production to recognize function calls:

expr     : /* ... */
         | ID LPAREN arguments RPAREN

arguments: /* empty */
         | exprs
exprs    : expr
         | exprs COMMA expr

That covers the grammar part. Trying to do any of this in the lexer violates the clear distinction between lexical analysis and parsing, which you might want to review. (Also, it will turn out to be infeasible, as you have discovered.)

In your semantic actions, you'll need to check to see what the ID in the function call is, and insert appropriate code if it turns out to be a system call.

Upvotes: 2

sqweek
sqweek

Reputation: 1187

What about array[0] or array[1]? Are they allowed? I don't see how fun_dec1 can match, because there's no return type specified here - I guess you have a function call definition in your grammar too, surely it would be matching that?

The one function call grammar definition should be sufficient, I'm not sure why you're trying to hardcode input/output functions into the grammar.

Upvotes: -1

Related Questions