return to first page linux journal archive
keywordscontents

Listing 3. yacc Interpretation Code

   1: %{
   2: /* err = do_arithmetic (struct LOGFILE *, 
               char * arithmetic_string)
   3:    This yacc program is designed to perform
         simple arithmetic on vectors, contained
   4:    (optionally) in multiple levels of
   5:    parentheses. 
    ---------------lines deleted------------
  20:   "do_arithmetic" returns:
  21:   	0 - normal processing completed
  22:   	1 - yyparse internal syntactical error
  23:   	2 - unpaired parentheses
  24:   	3 - more than 1 '=' sign
  25:   	4 - unrecognized curve name
  27:   Written by D. A. Provins, February, 1994
  28: */
    ---------------lines deleted------------
  35: #define MAGIC 999	/* used to indicate a 
                           temporary vector */
  36: #define STACKSIZE 200  /* value MUST be <
                                MAGIC */
  37: #define STRING_LEN 90  /* maximum length of 
                   string describing arithmetic */
  38: #define max(a,b) ((a) < (b) ? (a) : (b))
  39: int DeBuG = 0;   /* do_arithmetic sets if 
          environment "las_debug" set */
  40: int las_nocase = 0;    /* do_arithmetic sets
               if "las_nocase" valued */
    ---------------lines deleted------------
  68: static double * temp = NULL,  /* "holding"
                                        vector */
  69:        * vec1 = NULL,         /* one of 2 
                         containing real digits */
  70:        * vec2 = NULL,
  71:        * tmp [STACKSIZE];	    /* stacked 
                              temporary vectors */
  72: %}
  73: %token INTEGER FLOAT DOUBLE NUMBER VARIABLE\
	 EQUAL LPAREN
  74: %token RPAREN PLUS MINUS TIMES DIVIDE RAISE \
	LHS
  75: %left PLUS, MINUS
  76: %left TIMES, DIVIDE
  77: %left RAISE
  78: %%
  79: equation: 
  80:   lhs EQUAL expr {
  81:        pop (&code, &value);
  82:        get_curve (temp, code);
  83:        if (DeBuG) {
  84:         printf (
		"variable = expression equation\
recognized\\n");
  85:         if (!code)
  86:          printf ("Final scalar = <%f>\\n",
		 value);
  87:         else {
  88:          printf ("Final vector:\\n");
  89:          for (i = 0; i < num_digits; i++)
  90:           printf ("  %f\\n", temp [i]);
  91:         }
  92:         printf ("Final vector name: <%s>\\n", label);
  94:         while (stkptr)
  95:          pop (&code, &value);
  96:        }
  97:       }
  98:   | expr {
  99:       pop (&code, &value);   /* is this 
				     required?? */
  100:       get_curve (temp, code);
  101:       if (DeBuG) {
  102:        printf (
"non-replacement equation recognized\\n");
  103:        
  104:        if (!code)
  105:         printf ("Final scalar = <%f>\\n", value);
  106:        else {
  107:         printf ("Final vector:\\n");
  108:         for (i = 0; i < num_digits; i++)
  109:          printf ("  %f\\n", temp [i]);
  110:        }
  111:        printf ("Final vector name: <%s>\\n", label);
  113:        while (stkptr)
  114:         pop (&code, &value);
  115:       }
  116: 	  }
  117:   ;
  118: lhs  :
  119:    LHS   {
  120:         if ((code = which_curve \
			(yytext, curves)) == 0)
  121:          return 4;    /* unrecognized curve
                                name */
  122:         strcpy (label, yytext);
  123: 		 j = push (code, value);
  124:         if (DeBuG) {
  125:          printf ("code <%d> is lhs \
<%s>\\n", code, yytext);
  126:         }
  127:        }
  128: expr : 
  129:    NUMBER {
  130:         code = 0;	/* scalar value */
  131: 		 j = push (code, value);
  132:        }
  133:   | VARIABLE {
  134:         if ((code = which_curve \
		    (yytext, curves)) == 0)
  135:          return 4;    /* unrecognized curve
			        name */
  136: 		 j = push (code, value);
  137:         if (DeBuG)
  138:          printf ("code <%d> is vector\
 <%s>\\n", code, yytext);
  139:        }
    ---------------lines deleted------------
  426: %%
  427: /**********************do_arithmetic************************/
  428: int
  429: do_arithmetic (
  430: #ifdef _NO_PROTO
  431: LogFile, arithmetic_string)
  432: struct LOG_FILE * LogFile;
  433: char * arithmetic_string;
  434: #else
  435: struct LOG_FILE * LogFile;
       char * arithmetic_string);
  436: #endif
  437: {
  438:  int i, j;
  439:  char * str = NULL;
  440:  extern char * my_arithmetic_pointer,
  441:        * current_pointer,
  442:        * end_of_string_pointer;
    ---------------lines deleted------------
  475: /*	Ensure the parentheses match
  476: */
  477:  for (i = j = 0; i < strlen (my_arithmetic_string); i++)
  478:   if (my_arithmetic_string [i] == '(')
  479:    j++;
  480:   else if (my_arithmetic_string [i] == ')')
  481:    j--;
  482:  if (j) 
  483:   return 2;	/* unpaired parentheses detected */
    ---------------lines deleted------------
  493:  current_pointer = 
  494:   & my_arithmetic_string [0];
  495:  end_of_string_pointer = 
  496:   & my_arithmetic_string [strlen \
		(my_arithmetic_string)];
  497: /* Determine the unknown's name, and 
          do case switch if needed  */
  499:  for (i = j = 0; i < strlen \
		(my_arithmetic_string); i++)
  500:   if (my_arithmetic_string [i] == '=')
  501:    j++;
  502:   else
  503:    if (las_nocase)
  504: 	my_arithmetic_string [i] = 
  505: 	 (char) toupper ((int) \
		my_arithmetic_string [i]);
  506:  if (j > 1)
  507:   return 3;   /* more than one '=' */
  508:  if (j) {
  509:   strncpy (label, my_arithmetic_string, \
		max(j, STRING_LEN - 1));
  510:   label [j] = '\\0';
  511:  }
  512: /* Get the # of curves, # of digits and the 
          curve names. Add two additional
  513: 	  pointers to the curves array:
  514: 	  1 - NULL, or UNKNOWN (in case its needed)
  515: 	  2 - NULL terminator (for searching the 
  516:              array */
  517:  num_curves = LogFile -> num_curves;
  518:  num_digits = LogFile -> data_points;
  519:  null_value = LogFile -> WellInfo.null;
  520:  curves = (char **) malloc (sizeof (char *) *\
		(num_curves + 2));
  521:  for (i = 0; i < num_curves; i++)
  522:   curves [i] = LogFile -> \
		Curve [i].curve_name;
  523:  curves [num_curves + 0] = NULL;
  524:  curves [num_curves + 1] = NULL;
  525: /* If we don't recognize the name, 
          then we'll add it to the
  526: 	  list, otherwise, ignore it. */
  528:  if ((i = which_curve (label, curves)) == 0)
  529:   curves [num_curves + 0] = label;
  530:  do_initialization ();	/* assign space */
  531:  LogFileAddress = LogFile; /* get_digits 
                             needs this address */
  532:  err = yyparse ();  /* parse the statement;
                                    do the work */
  533:  restart_lex ();	   /* ensure we can do 
                         another arithmetic run */
  534: /*  err = 0: processing completed normally
  535: 	   1: yyparse internal syntactical error
  536: 	   2: unpaired parentheses
  537: 	   3: more than 1 equal sign
  538: 	   4: unrecognized curve n
  539: */
  540:  return err;
  541: }
    ---------------lines deleted------------
  557: /***************push*********************/
  558: int
  559: push (
  560: #ifdef _NO_PROTO
  561: code, value)
  562: int code; float value;
  563: #else
  564: int code, float value)
  565: #endif
  566: /* This routine "pushes" a code, and 
          optionally a value onto a stack.
  569:  code = 0: a scalar value, as a float is to
                  be added to the stack
  570:  code = 1+: the "code" indicates
              which curve is referenced and is to
  571:        be added to the stack
  572:  int push (int code, float value)
  573: */
  574: {
    ---------------lines deleted------------
  613: }
  614: /**************pop************************/
  615: int
  616: pop (
  617: #ifdef _NO_PROTO
  618: code, value)
  619: int * code; float * value;
  620: #else
  621: int * code, float * value)
  622: #endif
  623: /* This routine "pops" a code, 
          and optionally a value from the stack.
  626:  code = 0: a scalar value, as a float was 
                  removed from the stack the 
  627:            value and code are returned
  628:  code = 1+: the "code" indicates 
                   which curve is referenced and
  629:             was removed from the stack
  630:  int pop (int * code, float * value)
  631: */
  632: {
    ---------------lines deleted------------
  658: }
    -------many more lines deleted------------