[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: Newbie Dynamic Data Typing Help
From: |
Gill,Michael J |
Subject: |
RE: Newbie Dynamic Data Typing Help |
Date: |
Fri, 7 Oct 2005 15:13:54 -0400 |
Hans,
Thanks for the tips, I'm trying the %union approach but am hung up on
how to differentiate data types in the grammar. I need to initialize
VARs to either NUM or CHR types but only want to allow operations (+, -,
*, etc.) on NUM types, hoe do I differentiate VAR types in the grammar?
This is what I have now:
//data types
%union{
double num; //number & variable type
char chr; //char type
symrec *tptr; //symbol table pointers
}
%token <num> NUM //number
%token <chr> CHR //char
%token <tptr> VAR FNCT //variable and function
%type <num> numexp //set numexp type
%type <chr> chrexp //set chrexp type
%right '=' // assignment op
%left '-' '+' //add & sub
%left '*' '/' //multiply & divide
%left NEG /* negation--unary minus */
%right '^' /* exponentiation */
%% /* The grammar follows. */
input: /* empty */
| input line
;
line: ';' { printf ("\n%d> ", @$.last_line); }
| numexp ';' { printf ("\t= %.10g\n%d> ", $1, @$.last_line); }
| chrexp ';' { printf ("\t= %c\n%d> ", $1, @$.last_line); }
| error ';'
;
numexp: NUM { $$ = $1; }
| VAR ';' {
//check data type
//num
if($1->dtype == NUM){
$$ = $1->value.num;
//char
}else if($1->dtype == CHR){
$$ = $1->value.chr;
//init as num = 0
}else{
$$ = 0;
$1->dtype = NUM;
$1->value.num = 0;
}
}
| VAR '=' numexp {
$$ = $3;
$1->dtype = NUM;
$1->value.num = $3;
}
| FNCT '(' numexp ')' { $$ = (*($1->value.fnctptr))($3); }
| numexp '+' numexp { $$ = $1 + $3; }
| numexp '-' numexp { $$ = $1 - $3; }
| numexp '*' numexp { $$ = $1 * $3; }
| numexp '/' numexp { $$ = $1 / $3; }
| '-' numexp %prec NEG { $$ = -$2; }
| numexp '^' numexp { $$ = pow ($1, $3); }
| '(' numexp ')' { $$ = $2; }
| '!' VAR { $$ = system($2->name);}
;
chrexp: CHR { $$ = $1; }
| VAR '=' chrexp {
$$ = $3;
$1->dtype = CHR;
$1->value.chr = $3;
}
;
%%
Thanks,
-Mike
-----Original Message-----
From: Hans Aberg [mailto:address@hidden
Sent: Wednesday, October 05, 2005 7:02 PM
To: Gill,Michael J
Cc: Bison Help
Subject: Re: Newbie Dynamic Data Typing Help
[Please keep the cc to Help-Bison, as others may help.]
It is described in the Bison manual. The type indicated just selects
a field in the union.
On 5 Oct 2005, at 21:53, Gill,Michael J wrote:
> Hans,
> I'm not familiar with the statc type system in Bison, how does that
> work? My current vars are implemented as pointers to symrec from
> the .y
> file and hold only doubles in their value fields. Is it enough to
> simply add the types to the union in the definition of symrec and then
> set them from the grammar actions based on the return type from yylex?
> How about the exp type can it still be just double? The whole type
> matching of tokens to grammar rules to values is confusing me.
>
> Thanks again,
> -Mike
>
> On 5 Oct 2005, at 18:54, Gill,Michael J wrote:
>
>
>> I'm a complete newbie to bison and language semantics in general.
>> I'm
>> trying to extend the mfcalc.y example from the manual to allow
>> dynamically typed variables but am at a loss as to how to implement
>> them. I'm currently saving var names and values in the symbol.c
>> linked
>> list but with double vals only, I want to add char and char* types as
>> dynamic types. Any direction/help would be apprectiated.
>>
>
> If you write in C++, you can make a polymorphic class hierarchy,
> i.e., a root class object, and classes derived from a that. As a
> parser semantic type, one would use another class, maintaining a
> pointer object*, which may be combined with a reference count, in
> order to avoid unnecessary copying.
>
> Now, if you program in C, you just translate this picture; vice
> versa, the C++ constructs were developed in order to automate the
> corresponding C constructs. C requires more programming by hand, but
> is easier to make optimized work in. So in C, you might have a class
> (in pseudocode)
> enum type { DOUBLE, STRING, OTHER, ... };
>
> struct data {
> type type_;
> union {
> double double_;
> char* string_;
> void* other_;
> ...
> }:
> };
>
> #define YYSTYPE data
>
> Then use the type_ value to extract the right kind of data, making
> sure that (de-)allocations takes place correctly, etc.
>
> If you only need statically typed variables that can hold different
> values, then use the Bison feature %union, and instead of the type
> enum, use Bison statc type system to select the right union field.
> Use %destructor to cleanup during error recovery.
>
> Hans Aberg
>
>
>