home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / compcomp / bawk_new / bawkact.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-01-04  |  11.9 KB  |  452 lines

  1. /*
  2.  * Bawk C actions compiler
  3.  */
  4. #include <stdio.h>
  5. #include "bawk.h"
  6.  
  7. extern char *str_compile();  /* added PEB for CI C86 compile */
  8.  
  9. act_compile( actbuf )
  10. char *actbuf;  /* where tokenized actions are compiled into */
  11. {
  12.      Where = ACTION;
  13.      return stmt_compile( actbuf );
  14. }
  15.  
  16. pat_compile( actbuf )
  17. char *actbuf;  /* where tokenized actions are compiled into */
  18. {
  19.      Where = PATTERN;
  20.      return stmt_compile( actbuf );
  21. }
  22.  
  23. stmt_compile( actbuf )
  24. char *actbuf;  /* where tokenized actions are compiled into */
  25. {
  26.      /*
  27.       * Read and tokenize C actions from current input file into the
  28.       * action buffer.  Strip out comments and whitespace in the
  29.       * process.
  30.       */
  31.      char *actptr,  /* actbuf pointer */
  32.           *cp,      /* work pointer */
  33.           buf[MAXLINELEN];/* string buffer */
  34.      int  braces,        /* counts '{}' pairs - return when 0 */
  35.           parens,        /* counts '()' pairs */
  36.           i,        /* temp */
  37.           c;        /* current input character */
  38.  
  39.      braces = parens = 0;
  40.      actptr = actbuf;
  41.      while ( (c = getcharacter()) != -1 )
  42.      {
  43.           /*
  44.            * Skip over spaces, tabs and newlines
  45.            */
  46.           if ( c==' ' || c=='\t' || c=='\n' )
  47.                continue;
  48.           if ( c=='#' )
  49.           {
  50.                /*
  51.                 * Skip comments.  Comments start with a '#' and
  52.                 * end at the next newline.
  53.                 */
  54.                while ( (c = getcharacter()) != -1 && c!='\n' )
  55.                     ;
  56.                continue;
  57.           }
  58.  
  59.           if ( c=='{' )
  60.           {
  61.                if ( Where==PATTERN )
  62.                {
  63.                     /*
  64.                      * We're compiling a pattern. The '{' marks
  65.                      * the beginning of an action statement.
  66.                      * Push the character back and return.
  67.                      */
  68.                     ungetcharacter( '{' );
  69.                     break;
  70.                }
  71.                else
  72.                {
  73.                     /*
  74.                      * We must be compiling an action statement.
  75.                      * '{'s mark beginning of action or compound
  76.                      * statements.
  77.                      */
  78.                     ++braces;
  79.                     *actptr++ = T_LBRACE;
  80.                }
  81.           }
  82.           else if ( c=='}' )
  83.           {
  84.                *actptr++ = T_RBRACE;
  85.                if ( ! --braces )
  86.                     /*
  87.                      * Found the end of the action string
  88.                      */
  89.                     break;
  90.           }
  91.           else if ( c=='(' )
  92.           {
  93.                ++parens;
  94.                *actptr++ = T_LPAREN;
  95.           }
  96.           else if ( c==')' )
  97.           {
  98.                if ( --parens < 0 )
  99.                     error( "mismatched '()'", ACT_ERROR );
  100.                *actptr++ = T_RPAREN;
  101.           }
  102.           else if ( c==',' && !braces && !parens && Where==PATTERN )
  103.           {
  104.                /*
  105.                 * found a comma outside of any braces or parens-
  106.                 * this must be a regular expression seperator.
  107.                 */
  108.                ungetcharacter( ',' );
  109.                break;
  110.           }
  111.  
  112.           /*
  113.            * Check if it's a regular expression:
  114.            */
  115.           else if ( c=='/' )
  116.           {
  117.                /*
  118.                 * A '/' inside a pattern string starts a regular
  119.                 * expression.  Inside action strings, a '/' is
  120.                 * the division operator.
  121.                 */
  122.                if ( Where == PATTERN )
  123.                     goto dopattern;
  124.                else
  125.                     *actptr++ = T_DIV;
  126.           }
  127.           else if ( c=='@' )
  128.           {
  129. dopattern:
  130.                /*
  131.                 * Within action strings, only the '@' may be used to
  132.                 * delimit regular expressions
  133.                 */
  134.                *actptr++ = T_REGEXP;
  135.                ungetcharacter( c );
  136.                actptr += re_compile( actptr );
  137.           }
  138.  
  139.           /*
  140.            * symbol, string or constant:
  141.            */
  142.           else if ( alpha( c ) )
  143.           {
  144.                /*
  145.                 * It's a symbol reference. Copy the symbol into
  146.                 * string buffer.
  147.                 */
  148.                cp = buf;
  149.                do
  150.                     *cp++ = c;
  151.                while ( (c=getcharacter()) != -1 && alphanum( c ) );
  152.                ungetcharacter( c );
  153.                *cp = 0;
  154.                /*
  155.                 * Check if a keyword, builtin function or variable.
  156.                 */
  157.                if ( c = iskeyword( buf ) )
  158.                     *actptr++ = c;
  159.                else if ( i = isfunction( buf ) )
  160.                {
  161.                     *actptr++ = T_FUNCTION;
  162.                     storeint( actptr, i );
  163.                     actptr += sizeof( i );
  164.                }
  165.                else
  166.                {
  167.                     /*
  168.                      * It's a symbol name.
  169.                      */
  170.                     *actptr++ = T_VARIABLE;
  171.                     if ( !(cp = findvar( buf )) )
  172.                          cp = addvar( buf );
  173.                     storeptr( actptr, cp );
  174.                     actptr += sizeof( cp );
  175.                }
  176.           }
  177.  
  178.           else if ( c == '"' )
  179.           {
  180.                /*
  181.                 * It's a string constant
  182.                 */
  183.                *actptr++ = T_STRING;
  184.                actptr = str_compile( actptr, '"' );
  185.           }
  186.           else if ( c == '\'' )
  187.           {
  188.                /*
  189.                 * It's a character constant
  190.                 */
  191.                *actptr++ = T_CONSTANT;
  192.                str_compile( buf, '\'' );
  193.                storeint( actptr, *buf );
  194.                actptr += sizeof( i );
  195.           }
  196.  
  197.           else if ( num( c ) )
  198.           {
  199.                /*
  200.                 * It's a numeric constant
  201.                 */
  202.                *actptr++ = T_CONSTANT;
  203.                cp = buf;
  204.                do
  205.                     *cp++ = c;
  206.                while ( (c=getcharacter()) != -1 && num(c) );
  207.                ungetcharacter( c );
  208.                *cp = 0;
  209.                storeint( actptr, atoi( buf ) );
  210.                actptr += sizeof( i );
  211.           }
  212.  
  213.           /*
  214.            * unary operator:
  215.            */
  216.           else if ( c == '$' )
  217.                *actptr++ = T_DOLLAR;
  218.  
  219.           /*
  220.            * or binary operator:
  221.            */
  222.           else if ( c == '=' )
  223.           {
  224.                if ( (c=getcharacter()) == '=' )
  225.                     *actptr++ = T_EQ;
  226.                else
  227.                {
  228.                     ungetcharacter( c );
  229.                     *actptr++ = T_ASSIGN;
  230.                }
  231.           }
  232.  
  233.           else if ( c == '!' )
  234.           {
  235.                if ( (c=getcharacter()) == '=' )
  236.                     *actptr++ = T_NE;
  237.                else
  238.                {
  239.                     ungetcharacter( c );
  240.                     *actptr++ = T_LNOT;
  241.                }
  242.           }
  243.  
  244.           else if ( c == '<' )
  245.           {
  246.                if ( (c=getcharacter()) == '<' )
  247.                     *actptr++ = T_SHL;
  248.                else if ( c == '=' )
  249.                     *actptr++ = T_LE;
  250.                else
  251.                {
  252.                     ungetcharacter( c );
  253.                     *actptr++ = T_LT;
  254.                }
  255.           }
  256.  
  257.           else if ( c == '>' )
  258.           {
  259.                if ( (c=getcharacter()) == '>' )
  260.                     *actptr++ = T_SHR;
  261.                else if ( c == '=' )
  262.                     *actptr++ = T_GE;
  263.                else
  264.                {
  265.                     ungetcharacter( c );
  266.                     *actptr++ = T_GT;
  267.                }
  268.           }
  269.  
  270.           else if ( c == '&' )
  271.           {
  272.                if ( (c=getcharacter()) == '&' )
  273.                     *actptr++ = T_LAND;
  274.                else
  275.                {
  276.                     ungetcharacter( c );
  277.                     *actptr++ = T_AND;
  278.                }
  279.           }
  280.  
  281.           else if ( c == '|' )
  282.           {
  283.                if ( (c=getcharacter()) == '|' )
  284.                     *actptr++ = T_LIOR;
  285.                else
  286.                {
  287.                     ungetcharacter( c );
  288.                     *actptr++ = T_IOR;
  289.                }
  290.           }
  291.           else if ( c == '+' )
  292.           {
  293.                if ( (c=getcharacter()) == '+' )
  294.                     *actptr++ = T_INCR;
  295.                else
  296.                {
  297.                     ungetcharacter( c );
  298.                     *actptr++ = T_ADD;
  299.                }
  300.           }
  301.  
  302.           else if ( c == '-' )
  303.           {
  304.                if ( (c=getcharacter()) == '-' )
  305.                     *actptr++ = T_DECR;
  306.                else
  307.                {
  308.                     ungetcharacter( c );
  309.                     *actptr++ = T_SUB;
  310.                }
  311.           }
  312.  
  313.           /*
  314.            * punctuation
  315.            */
  316.           else if ( instr( c, "[](),;*/%+-^~" ) )
  317.                *actptr++ = c;
  318.  
  319.           else
  320.           {
  321.                /*
  322.                 * Bad character in input line
  323.                 */
  324.                error( "lexical error", ACT_ERROR );
  325.           }
  326.  
  327.           if ( actptr >= Workbuf + MAXWORKBUFLEN )
  328.                error( "action too long", MEM_ERROR );
  329.      }
  330.      if ( braces || parens )
  331.           error( "mismatched '{}' or '()'", ACT_ERROR );
  332.  
  333.      *actptr++ = T_EOF;
  334.  
  335.      return actptr - actbuf;
  336. }
  337.  
  338. char *str_compile( str, delim )
  339. char *str, delim;
  340. {
  341.      /*
  342.       * Compile a string from current input file into the given string
  343.       * buffer.  Stop when input character is the delimiter in "delim".
  344.       * Returns a pointer to the first character after the string.
  345.       */
  346.      int c;
  347.      char buf[ MAXLINELEN ];
  348.  
  349.      while ( (c = getcharacter()) != -1 && c != delim)
  350.      {
  351.           if ( c  == '\\' )
  352.           {
  353.                switch ( c = getcharacter() )
  354.                {
  355.                case -1: goto err;
  356.                case 'b': c = '\b'; break;
  357.                case 'n': c = '\n'; break;
  358.                case 't': c = '\t'; break;
  359.                case 'f': c = '\f'; break;
  360.                case 'r': c = '\r'; break;
  361.                case '0':
  362.                case '1':
  363.                case '2':
  364.                case '3':
  365.                     *buf = c;
  366.                     for ( c=1; c<3; ++c )
  367.                     {
  368.                          if ( (buf[c]=getcharacter()) == -1 )
  369.                               goto err;
  370.                     }
  371.                     buf[c] = 0;
  372.                     sscanf( buf, "%o", &c );
  373.                     break;
  374.                case '\n':
  375.                     if ( getcharacter() == -1 )
  376.                          goto err;
  377.                default:
  378.                     if ( (c = getcharacter()) == -1 )
  379.                          goto err;
  380.                }
  381.           }
  382.           *str++ = c;
  383.      }
  384.      *str++ = 0;
  385.  
  386.      return str;
  387. err:
  388.      sprintf( buf, "missing %c delimiter", delim );
  389.      error( buf, 4 );
  390. }
  391.  
  392. storeint( ip, i )
  393. int *ip, i;
  394. {
  395.      return *ip = i;
  396. }
  397.  
  398. storeptr( pp, p )
  399. char **pp, *p;
  400. {
  401.      return *pp = p;
  402. }
  403.  
  404. fetchint( ip )
  405. int *ip;
  406. {
  407.      return *ip;
  408. }
  409.  
  410. char *
  411. fetchptr( pp )
  412. char **pp;
  413. {
  414.      return *pp;
  415. }
  416.  
  417. getoken()
  418. {
  419.      char *cp;
  420.      int i;
  421.  
  422.      switch ( Token = *Actptr++ )
  423.      {
  424.      case T_STRING:
  425.      case T_REGEXP:
  426.           Value.dptr = Actptr;
  427.           Actptr += strlen( Actptr ) + 1;
  428.           break;
  429.      case T_VARIABLE:
  430.           Value.dptr = fetchptr( Actptr );
  431.           Actptr += sizeof( cp );
  432.           break;
  433.      case T_FUNCTION:
  434.      case T_CONSTANT:
  435.           Value.ival = fetchint( Actptr );
  436.           Actptr += sizeof( i );
  437.           break;
  438.      case T_EOF:
  439.           --Actptr;
  440.      default:
  441.           Value.dptr = 0;
  442.      }
  443.  
  444. #ifdef DEBUG
  445.      if ( Debug > 1 )
  446.           printf( "Token='%c' (0x%x), Value=%d\n",
  447.                Token,Token,Value.ival );
  448. #endif
  449.  
  450.      return Token;
  451. }
  452.