[Top][All Lists]
[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