"Fossies" - the Fresh Open Source Software Archive

Member "teapot-2.3.0/parser.c" (6 Feb 2012, 7345 Bytes) of package /linux/privat/old/teapot-2.3.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "parser.c" see the Fossies "Dox" file reference documentation.

    1 /* #includes */ /*{{{C}}}*//*{{{*/
    2 #ifndef NO_POSIX_SOURCE
    3 #undef _POSIX_SOURCE
    4 #define _POSIX_SOURCE   1
    5 #undef _POSIX_C_SOURCE
    6 #define _POSIX_C_SOURCE 2
    7 #endif
    8 
    9 #ifdef DMALLOC
   10 #include "dmalloc.h"
   11 #endif
   12 
   13 #include <assert.h>
   14 #include <ctype.h>
   15 #include <stdio.h>
   16 #include <stdlib.h>
   17 #include <string.h>
   18 
   19 
   20 #include "eval.h"
   21 #include "main.h"
   22 #include "misc.h"
   23 #include "parser.h"
   24 #include "scanner.h"
   25 #include "sheet.h"
   26 /*}}}*/
   27 /* #defines */ /*{{{*/
   28 #define MAXARGC 16
   29 /*}}}*/
   30 
   31 /* prototypes */ /*{{{*/
   32 static Token term(Token *n[], int *i);
   33 /*}}}*/
   34 
   35 /* primary   -- parse and evaluate a primary term */ /*{{{*/
   36 static Token primary(Token *n[], int *i)
   37 {
   38   /* variables */ /*{{{*/
   39   int argc,j;
   40   Token *ident,argv[MAXARGC],result;
   41   /*}}}*/
   42 
   43   if (n[*i]==(Token*)0)
   44   /* error */ /*{{{*/
   45   {
   46     result.type=EEK;
   47     result.u.err=strcpy(malloc(strlen(_("missing operator"))+1),_("missing operator"));
   48     return result;
   49   }
   50   /*}}}*/
   51   else switch (n[*i]->type)
   52   {
   53     /* STRING, FLOAT, INT */ /*{{{*/
   54     case STRING:
   55     case FLOAT:
   56     case INT:
   57     {
   58       return tcopy(*n[(*i)++]);
   59     }
   60     /*}}}*/
   61     /* OPERATOR */ /*{{{*/
   62     case OPERATOR:
   63     {
   64       if (n[*i]->u.op==OP)
   65       /* return paren term */ /*{{{*/
   66       {
   67         ++(*i);
   68         result=term(n,i);
   69         if (result.type==EEK) return result;
   70         if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==CP) 
   71         {
   72           ++(*i);
   73           return result;
   74         }
   75         tfree(&result);
   76         result.type=EEK;
   77         result.u.err=strcpy(malloc(strlen(_(") expected"))+1),_(") expected"));
   78         return result;
   79       }
   80       /*}}}*/
   81       else if (n[*i]->u.op==MINUS)
   82       /* return negated term */ /*{{{*/
   83       {
   84         ++(*i);
   85         return(tneg(primary(n,i)));
   86       }
   87       /*}}}*/
   88       else
   89       /* return error, value expected */ /*{{{*/
   90       {
   91         result.type=EEK;
   92         result.u.err=mystrmalloc(_("value expected"));
   93         return result;
   94       }
   95       /*}}}*/
   96     }  
   97     /*}}}*/
   98     /* LIDENT */ /*{{{*/
   99     case LIDENT:
  100     {
  101       ident=n[*i];
  102       ++(*i);
  103       return findlabel(upd_sheet,ident->u.lident);
  104     }
  105     /*}}}*/
  106     /* FIDENT */ /*{{{*/
  107     case FIDENT:
  108     {
  109       ident=n[*i];
  110       ++(*i);
  111       if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==OP)
  112       /* parse arguments and closing paren of function call, return its value */ /*{{{*/
  113       {
  114         ++(*i);
  115         argc=0;
  116         if (!(n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==CP))
  117         /* parse at least one argument */ /*{{{*/
  118         {
  119           if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==COMMA)
  120           /* empty argument */ /*{{{*/
  121           {
  122             argv[argc].type=EMPTY;
  123           }
  124           /*}}}*/
  125           else argv[argc]=term(n,i);
  126           if (argv[argc].type==EEK) return argv[argc];
  127           ++argc;
  128           while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==COMMA)
  129           /* parse the following argument */ /*{{{*/
  130           {
  131             ++(*i);
  132             if (argc<=MAXARGC)
  133             {
  134               if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && (n[*i]->u.op==COMMA || n[*i]->u.op==CP))
  135               {
  136                 argv[argc].type=EMPTY;
  137               }    
  138               else argv[argc]=term(n,i);
  139             }
  140             else
  141             {
  142               result.type=EEK;
  143               result.u.err=strcpy(malloc(strlen(_("too many arguments"))+1),_("too many arguments"));
  144               for (j=0; j<=argc; ++j) tfree(&argv[j]);
  145               return result;
  146             }
  147             ++argc;
  148           }
  149           /*}}}*/
  150         }
  151         /*}}}*/
  152         if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==CP) 
  153         /* eval function */ /*{{{*/
  154         {
  155           ++(*i);
  156           result=tfuncall(ident,argc,argv);  
  157           for (j=0; j<argc; ++j) tfree(&argv[j]);
  158         }
  159         /*}}}*/
  160         else
  161         /* ) expected */ /*{{{*/
  162         {
  163           for (j=0; j<argc; ++j) tfree(&argv[j]);
  164           result.type=EEK;
  165           result.u.err=strcpy(malloc(strlen(_(") expected"))+1),_(") expected"));
  166         }
  167         /*}}}*/
  168         return result;  
  169       }
  170       /*}}}*/
  171       else
  172       { 
  173         result.type=EEK;
  174         result.u.err=mystrmalloc(_("( expected"));
  175         return result;
  176       }
  177     }
  178     /*}}}*/
  179     default: ; /* fall through */
  180   }
  181   result.type=EEK;
  182   result.u.err=mystrmalloc(_("value expected"));
  183   return result;
  184 }
  185 /*}}}*/
  186 /* powterm   -- parse and evaluate a x^y term */ /*{{{*/
  187 static Token powterm(Token *n[], int *i)
  188 {
  189   Token l;
  190 
  191   l=primary(n,i);
  192   if (l.type==EEK) return l;
  193   while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==POW)
  194   {
  195     Token result,r;
  196 
  197     ++(*i);
  198     r=primary(n,i);
  199     result=tpow(l,r);
  200     tfree(&l);
  201     tfree(&r);
  202     if (result.type==EEK) return result;
  203     l=result;
  204   }
  205   return l;
  206 }
  207 /*}}}*/
  208 /* piterm    -- parse and evaluate a product/division/modulo term */ /*{{{*/
  209 static Token piterm(Token *n[], int *i)
  210 {
  211   Token l;
  212 
  213   l=powterm(n,i);
  214   if (l.type==EEK) return l;
  215   while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && (n[*i]->u.op==DIV || n[*i]->u.op==MUL || n[*i]->u.op==MOD))
  216   {
  217     Operator op;
  218     Token result,r;
  219 
  220     op=n[*i]->u.op;    
  221     ++(*i);
  222     r=powterm(n,i);
  223     switch (op)
  224     {
  225       case MUL: result=tmul(l,r); break;
  226       case DIV: result=tdiv(l,r); break;
  227       case MOD: result=tmod(l,r); break;
  228       default: assert(0);
  229     }
  230     tfree(&l);
  231     tfree(&r);
  232     if (result.type==EEK) return result;
  233     l=result;
  234   }
  235   return l;
  236 }
  237 /*}}}*/
  238 /* factor    -- parse and evaluate a factor of sums/differences */ /*{{{*/
  239 static Token factor(Token *n[], int *i)
  240 {
  241   Token l;
  242 
  243   l=piterm(n,i);
  244   if (l.type==EEK) return l;
  245   while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && (n[*i]->u.op==PLUS || n[*i]->u.op==MINUS))
  246   {
  247     Operator op;
  248     Token result,r;
  249 
  250     op=n[*i]->u.op;    
  251     ++(*i);
  252     r=piterm(n,i);
  253     result=(op==PLUS ? tadd(l,r) : tsub(l,r));
  254     tfree(&l);
  255     tfree(&r);
  256     if (result.type==EEK) return result;
  257     l=result;
  258   }
  259   return l;
  260 }
  261 /*}}}*/
  262 /* term      -- parse and evaluate a relational term */ /*{{{*/
  263 static Token term(Token *n[], int *i)
  264 {
  265   Token l;
  266 
  267   l=factor(n,i);
  268   if (l.type==EEK) return l;
  269   while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op>=LT && n[*i]->u.op<=NE)
  270   {
  271     Operator op;
  272     Token result,r;
  273 
  274     op=n[*i]->u.op;    
  275     ++(*i);
  276     r=factor(n,i);
  277     switch (op)
  278     {
  279       case LT: result=tlt(l,r); break;
  280       case LE: result=tle(l,r); break;
  281       case GE: result=tge(l,r); break;
  282       case GT: result=tgt(l,r); break;
  283       case ISEQUAL: result=teq(l,r); break;
  284       case ABOUTEQ: result=tabouteq(l,r); break;
  285       case NE: result=tne(l,r); break;
  286       default: assert(0);
  287     }
  288     tfree(&l);
  289     tfree(&r);
  290     if (result.type==EEK) return result;
  291     l=result;
  292   }
  293   return l;
  294 }
  295 /*}}}*/
  296 
  297 /* eval      -- parse and evaluate token sequence */ /*{{{*/
  298 Token eval(Token **n)
  299 {
  300   Token result;
  301   int i;
  302 
  303   assert(upd_sheet!=(Sheet*)0);
  304   i=0;
  305   result=term(n,&i);
  306   if (result.type==EEK) return result;
  307   if (n[i]!=(Token*)0)
  308   {
  309     tfree(&result);
  310     result.type=EEK;
  311     result.u.err=strcpy(malloc(strlen(_("parse error after term"))+1),_("parse error after term"));
  312     return result;
  313   }
  314   return result;
  315 }
  316 /*}}}*/