home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- *
- * Copyright (c) 1993 Ke Jin
- *
- * Permission to use, copy, modify, and distribute
- * this software and its documentation without fee
- * is granted, provided that the author's name and
- * this copyright notice are retained.
- *
- * ------------------------------------------------------------
- *
- * dfcparse.y -- the yacc file of defunc parser
- *
- * public function : yyparse();
- * yyinit();
- * getparsetree();
- *
- * public variable : exparserror;
- *
- * private function : addnode();
- * yyreverse();
- * yyerror();
- * yywrap();
- *
- * private variable : yyparsetree;
- * yytreesize;
- * newnode;
- *
- ****************************************************************/
-
- %{
- #include <stdio.h>
- #include <malloc.h>
- #include <math.h>
- #include <string.h>
- #include "dfctree.h"
- #include "dfcsymtable.h"
-
- char* exparserror;
- static char ermsgbuff[128];
- static Node* yyparsetree;
- static int yytreesize;
- static Node newnode;
-
- #if NeedFunctionPrototypes
- int yyparse(void);
- static int yyreverse(void);
- #else
- extern int yyparse();
- extern int yyreverse();
- #endif
-
- #if NeedFunctionPrototypes
- static int addnode(Node *ptr)
- #else
- static int addnode(ptr)
- Node *ptr;
- #endif
- {
- yytreesize++;
-
- if(yytreesize==1)
- {
- yyparsetree = (Node*)malloc(sizeof(Node));
- }
- else
- {
- yyparsetree = (Node*)realloc((Node*)yyparsetree,
- yytreesize*sizeof(Node));
- }
- if(yyparsetree==0)
- {
- perror("malloc/realloc in addnode()");
- exit(1);
- }
-
- if(yyparsetree == 0)
- {
- fprintf(stderr, "fail to allocate memory in add node\n");
- exit(1);
- }
-
- /* yyparsetree[yytreesize-1] = *ptr; */
- memcpy(yyparsetree+yytreesize-1, ptr, sizeof(Node));
-
- return yytreesize-1;
- };
-
- %}
-
- %union {
- int nodeidx;
- int argidx;
- double value;
- double (*fnctptr)();
- char name[32];
- }
-
- %token <value> CONST /* constant */
- %token <argidx> ARG /* function arguments */
- %token <fnctptr> FNCT /* intrinsic function */
- %token <name> SYM /* new symbol */
- %type <nodeidx> expr /* function expression */
-
- %left '-' '+'
- %left '*' '/'
- %left SIG
- %right '^'
-
- %% /* ------------------- syntax rules ------------------------ */
- input : '\n' {
- return 0;
- }
- | ';' {
- return 0;
- }
- | expr '\n' {
- return yyreverse();
- }
- | expr ';' {
- return yyreverse();
- }
- | error '\n' {
- return -1;
- }
- ;
-
- expr : CONST {
- newnode.type = const_node;
- newnode.content.value = $1;
-
- $$ = addnode(&newnode);
- }
- | SYM {
- sprintf(ermsgbuff,
- "unknow token \"%s\"", $1);
- exparserror = ermsgbuff;
- return -1;
- }
- | CONST '(' ')' {
- newnode.type = const_node;
- newnode.content.value = $1;
-
- $$ = addnode(&newnode);
- }
- | CONST '(' expr ')' {
- newnode.type = const_node;
- newnode.content.value = $1;
-
- $$ = addnode(&newnode);
- }
- | ARG {
- newnode.type = arg_node;
- newnode.content.argidx = $1;
- $$ = addnode(&newnode);
- }
- | FNCT '(' expr ')' {
- newnode.type = simplex_fnct_node;
- newnode.content.fnctptr = $1;
- newnode.right = $3;
-
- $$ = addnode(&newnode);
- }
- | FNCT '(' expr ',' expr ')' {
- newnode.type = duplex_fnct_node;
- newnode.content.fnctptr = $1;
- newnode.left = $3;
- newnode.right= $5;
-
- $$ = addnode(&newnode);
- }
- | FNCT '(' expr ',' expr ',' expr ')' {
- exparserror
- = "not support triplex function yet";
- return -1;
- }
- | expr '+' expr {
- newnode.type = binary_op_node;
- newnode.content.op = op_sum;
- newnode.left = $1;
- newnode.right= $3;
-
- $$ = addnode(&newnode);
- }
- | expr '-' expr {
- newnode.type = binary_op_node;
- newnode.content.op = op_sub;
- newnode.left = $1;
- newnode.right= $3;
-
- $$ = addnode(&newnode);
- }
- | expr '*' expr {
- newnode.type = binary_op_node;
- newnode.content.op = op_mul;
- newnode.left = $1;
- newnode.right= $3;
-
- $$ = addnode(&newnode);
- }
- | expr '/' expr {
- newnode.type = binary_op_node;
- newnode.content.op = op_div;
- newnode.left =$1;
- newnode.right=$3;
-
- $$ = addnode(&newnode);
- }
- | '-' expr %prec SIG {
- newnode.type = unary_op_node;
- newnode.content.op = op_neg;
- newnode.right = $2;
-
- $$ = addnode(&newnode);
- }
- | '+' expr %prec SIG {
- $$ = $2;
- }
- | expr '^' expr {
- newnode.type = duplex_fnct_node;
- newnode.content.fnctptr = pow;
- newnode.left = $1;
- newnode.right= $3;
-
- $$ = addnode(&newnode);
- }
- | '(' expr ')' {
- $$ = $2;
- }
- ;
- %% /* --------------------------------------------------------- */
- #include "dfcscan.h"
-
- #if NeedFunctionPrototype
- int yyinit(char* expr)
- #else
- int yyinit(expr)
- char *expr;
- #endif
- {
- initargu();
-
- yyexpr = expr;
- yyexprlen = strlen(yyexpr);
- yypos = 0;
- yytreesize = 0;
-
- return 0;
- };
-
- #if NeedFunctionPrototypes
- static int yyreverse(void)
- #else
- static int yyreverse()
- #endif
- /* yyparse() use a LALR(1) bottom-up algorithem to construct the
- parse tree. Thus the result tree is upsetdown, i.e. the root
- is place on the end of the yyparsetree[]. yyreverse make it
- in right order, i.e. yyparsetree[0] be the root */
- {
- int i;
- Node* buff;
-
- if(yytreesize==0) return 0;
-
- buff = (Node*)malloc(sizeof(Node)*yytreesize);
- if(buff==0)
- {
- perror("malloc in reverse()");
- exit(1);
- }
-
- for(i=0; i<yytreesize; i++) /* reverse */
- {
-
- /* buff[i] = yyparsetree[yytreesize-1-i]; */
- memcpy(buff+i, yyparsetree+yytreesize-1-i, sizeof(Node));
- buff[i].left = yytreesize - 1 - buff[i].left;
- buff[i].right= yytreesize - 1 - buff[i].right;
-
- }
-
- for(i=0; i<yytreesize; i++) /* put it back */
- {
- yyparsetree[i] = buff[i];
- }
-
- free(buff);
-
- return yytreesize;
- };
-
- #if NeedFunctionPrototypes
- int getparsetree(Node* buff)
- #else
- int getparsetree(buff)
- Node* buff;
- #endif
- /* copy the parse into buff */
- {
- int i;
-
- for(i=0; i<yytreesize; i++)
- {
- buff[i] = yyparsetree[i];
- }
-
- return yytreesize;
- };
-
- #if NeedFunctionPrototypes
- static void yyerror(char* s)
- #else
- static yyerror(s)
- char *s;
- #endif
- {
- exparserror=s;
- };
-
- #if NeedFunctionPrototypes
- static int yywrap(void)
- #else
- static int yywrap()
- #endif
- {
- return 1;
- };
-