help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Extending Functions from Manual Example


From: Hans Aberg
Subject: Re: Extending Functions from Manual Example
Date: Fri, 12 Sep 2008 10:17:26 +0200

On 12 Sep 2008, at 03:12, Jason Melbye wrote:

On Thu, Sep 11, 2008 at 6:44 AM, Hans Aberg <address@hidden> wrote:
On 11 Sep 2008, at 05:17, Jason Melbye wrote:

Then use it:
 FNCT '(' expr ')'

Some prefer not using the '...' construct. So one can write:

%token LP "("
%token RP ")"

 FNCT "(" expr ")"


Should those FNCT '(' expr ')' / FNCT "(" expr ")" lines say FNCT '('
expr_list ')' (or "(", ")" ) instead? I'm still struggling to construct the action that calls the function as well, passing all the arguments. So say I
had this:

expr:    NUM
        | expr '+' expr {$$ = $1 + $2; }
        ... other basic math ...
        | FNCT '(' expr_list ')' { what goes here? }

and expr_list is as you suggest above.

It depends on what you return from the lexer (typically generated using Flex). If the lexer says
 return '(';
use that in the grammar. If it says
 return LP;
use LP or (if defined using %token as above) "(".

Sorry if I was unclear. I understand the difference between using '(' or "(", I was trying to ask if the symbol between the parenthesis should have been expr_list rather than expr.

Yes, typo, it should be as in the rule
  FNCT '(' expr_list ')'
and so on.

I'm not sure how to actually call the function, because I'm passing it a
variable amount of parameters - as many as make up expr_list.

You have to write a function that can handle it.

You need to create a data type that can hold the expr list. Then write code to compute the function application. Such data structures are called "closures", that is, they represent code that should be computed later. This is necessary for doing loops, too.

So the action code should look something like in pseudocode:
expr_list:
  expr {
    $$ = list($1);
  }
 | expr_list "," expr {
    $$ = append($1, $3);
  }
;

I'm not sure I completely follow the bit about creating a closure and computing later.

It becomes clearer when you implement loops. Then all parsed data must be put intoa data structure, and then evaluate it at a later point, when the parsing of the loop has been finished.

But I think I see how to do this now (or at least one way to do this.) Rather than have my C functions that I wish to call of the form fnct(arg1, arg2, ..., argn) where n is variable, I could just have them all of the form fnct(int argc, param_list *params), kind of like how main works. I could keep some information about them like how many and what types of parameters they take and do a little checking before invoking them to make sure I have a proper set of parameters.

This is your choice how you want to implement the actions, once the list and function has been parsed, and it is time to combine.

  Hans






reply via email to

[Prev in Thread] Current Thread [Next in Thread]