home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / AWK.ZIP / AWK.C next >
Encoding:
C/C++ Source or Header  |  1988-09-09  |  54.4 KB  |  1,989 lines

  1. /**
  2.  * $Revision:   1.1  $
  3.  * $Log:   C:/AWK/AWK.C_V  $
  4.  * 
  5.  *    Rev 1.1   09 Sep 1988 18:32:40   vince
  6.  * MC 5.1 version
  7.  * 
  8.  *    Rev 1.0   09 Sep 1988 18:03:32   vince
  9.  * Original source
  10.  */
  11.  
  12. #define NAME         258
  13. #define REGEXP       259
  14. #define YSTRING      260
  15. #define ERROR        261
  16. #define INCDEC       262
  17. #define NUMBER       263
  18. #define ASSIGNOP     264
  19. #define RELOP        265
  20. #define MATCHOP      266
  21. #define NEWLINE      267
  22. #define REDIRECT_OP  268
  23. #define CONCAT_OP    269
  24. #define LEX_BEGIN    270
  25. #define LEX_END      271
  26. #define LEX_IF       272
  27. #define LEX_ELSE     273
  28. #define LEX_WHILE    274
  29. #define LEX_FOR      275
  30. #define LEX_BREAK    276
  31. #define LEX_CONTINUE 277
  32. #define LEX_GETLINE  278
  33. #define LEX_PRINT    279
  34. #define LEX_PRINTF   280
  35. #define LEX_NEXT     281
  36. #define LEX_EXIT     282
  37. #define LEX_IN       283
  38. #define LEX_AND      284
  39. #define LEX_OR       285
  40. #define INCREMENT    286
  41. #define DECREMENT    287
  42. #define LEX_BUILTIN  288
  43. #define LEX_SUB      289
  44. #define UNARY        290
  45.  
  46. #define YYDEBUG 12
  47.  
  48. #include <stdio.h>
  49. #include <string.h>
  50. #include "awk.h"
  51.  
  52. static int yylex();
  53.  
  54. /**
  55.  * The following variable is used for a very sickening thing.
  56.  * The awk language uses white space as the string concatenation
  57.  * operator, but having a white space token that would have to appear
  58.  * everywhere in all the grammar rules would be unbearable.
  59.  * It turns out we can return CONCAT_OP exactly when there really
  60.  * is one, just from knowing what kinds of other tokens it can appear
  61.  * between (namely, constants, variables, or close parentheses).
  62.  * This is because concatenation has the lowest priority of all
  63.  * operators.  want_concat_token is used to remember that something
  64.  * that could be the left side of a concat has just been returned.
  65.  *
  66.  * If anyone knows a cleaner way to do this (don't look at the Un*x
  67.  * code to find one, though), please suggest it.
  68.  */
  69. static int want_concat_token;
  70.  
  71. /* Two more horrible kludges.  The same comment applies to these two too */
  72. static int want_regexp;                /* lexical scanning kludge */
  73. static int want_redirect;              /* similarly */
  74. int lineno = 1;                        /* JF for error msgs */
  75.  
  76. /*
  77.  * Speaking of kludges.  We don't want to treat arguments as filenames
  78.  * if there are no pattern action pairs to perform; sooo I am creating
  79.  * a counter for patterns and actions. -ADE 
  80.  */
  81. int patterns = 0;
  82. int actions = 0;
  83. /*
  84.  * During parsing of a gawk program, the pointer to the next character is in this variable.  
  85.  */
  86. char *lexptr;                          /* JF moved it up here */
  87. char *lexptr_begin;                    /* JF for error msgs */
  88.  
  89. typedef union
  90. {
  91.    long lval;
  92.    AWKNUM fval;
  93.    NODE *nodeval;
  94.    NODETYPE nodetypeval;
  95.    char *sval;
  96.    NODE *(*ptrval) ();
  97. } YYSTYPE;
  98.  
  99. #ifndef YYLTYPE
  100. typedef struct yyltype
  101. {
  102.    int timestamp;
  103.    int first_line;
  104.    int first_column;
  105.    int last_line;
  106.    int last_column;
  107.    char *text;
  108. } yyltype;
  109.  
  110. #define YYLTYPE yyltype
  111. #endif
  112.  
  113. #define YYACCEPT return(0)
  114. #define YYABORT  return(1)
  115. #define YYERROR  return(1)
  116. #include <stdio.h>
  117.  
  118. #define YYFINAL         204
  119. #define YYFLAG          -32768
  120. #define YYNTBASE        54
  121.  
  122. #define YYTRANSLATE(x) (yytranslate[x])
  123.  
  124. static char yytranslate[] = {
  125.    0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  126.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  127.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  128.    2, 2, 43, 2, 2, 51, 40, 2, 2, 44,
  129.    45, 38, 36, 35, 37, 2, 39, 2, 2, 2,
  130.    2, 2, 2, 2, 2, 2, 2, 53, 48, 2,
  131.    2, 2, 52, 2, 2, 2, 2, 2, 2, 2,
  132.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  133.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  134.    49, 2, 50, 41, 2, 2, 2, 2, 2, 2,
  135.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  136.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  137.    2, 2, 46, 2, 47, 2, 2, 2, 2, 2,
  138.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  139.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  140.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  141.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  142.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  143.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  144.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  145.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  146.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  147.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  148.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  149.    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  150.    2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
  151.    6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  152.    16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
  153.    26, 27, 28, 29, 30, 31, 32, 33, 34, 42
  154. };
  155.  
  156. static short yyrline[] = {
  157.    0, 118, 124, 126, 132, 142, 144, 150, 152, 157, 159,
  158.       162, 164, 166, 168, 173, 175, 177, 183, 185, 191,
  159.       193, 195, 197, 199, 204, 209, 211, 217, 219, 225,
  160.       228, 236, 238, 240, 242, 244, 246, 249, 251, 254,
  161.       257, 259, 261, 263, 269, 271, 277, 279, 285, 288,
  162.       297, 298, 303, 305, 310, 312, 320, 322, 329, 331,
  163.       336, 338, 343, 345, 347, 349, 351, 353, 356, 358,
  164.       363, 367, 370, 372, 374, 379, 381, 387, 389, 391,
  165.       393, 395, 400, 402, 404, 406, 408, 413, 415, 417,
  166.       422, 424, 426, 431, 433, 438, 440, 445, 447, 452,
  167.       454, 459, 464, 466, 467, 468, 469
  168. };
  169.  
  170. static char *yytname[] = {
  171.    0, "error", "$illegal.", "NAME", "REGEXP", "YSTRING", "ERROR", "INCDEC", "NUMBER", "ASSIGNOP", "RELOP",
  172.    "MATCHOP", "NEWLINE", "REDIRECT_OP", "CONCAT_OP", "LEX_BEGIN", "LEX_END", "LEX_IF", "LEX_ELSE", "LEX_WHILE", "LEX_FOR",
  173.    "LEX_BREAK", "LEX_CONTINUE", "LEX_GETLINE", "LEX_PRINT", "LEX_PRINTF", "LEX_NEXT", "LEX_EXIT", "LEX_IN", "LEX_AND", "LEX_OR",
  174.    "INCREMENT", "DECREMENT", "LEX_BUILTIN", "LEX_SUB", "','", "'+'", "'-'", "'*'", "'/'", "'%'",
  175.    "'^'", "UNARY", "'!'", "'('", "')'", "'{'", "'}'", "';'", "'['", "']'",
  176.    "'$'", "'?'", "':'", "start"
  177. };
  178.  
  179. static short yyr1[] = {
  180.    0, 54, 55, 55, 56, 57, 57, 57, 57, 58, 58,
  181.       58, 58, 58, 58, 58, 58, 58, 59, 59, 60,
  182.       60, 60, 60, 60, 61, 62, 62, 63, 63, 64,
  183.       64, 66, 65, 67, 65, 68, 65, 69, 65, 65,
  184.       65, 65, 65, 65, 71, 70, 72, 70, 73, 70,
  185.       74, 74, 75, 75, 77, 76, 78, 78, 79, 79,
  186.       80, 80, 81, 81, 81, 81, 81, 81, 82, 81,
  187.       81, 83, 83, 83, 83, 84, 84, 85, 85, 85,
  188.       85, 85, 86, 86, 86, 86, 86, 87, 87, 87,
  189.       88, 88, 88, 89, 89, 90, 90, 91, 91, 92,
  190.       92, 93, 94, 94, 94, 94, 94
  191. };
  192.  
  193. static short yyr2[] = {
  194.    0, 2, 1, 2, 4, 0, 1, 1, 1, 1, 1,
  195.    2, 3, 3, 3, 3, 3, 3, 0, 1, 2,
  196.    1, 1, 1, 1, 4, 1, 2, 2, 2, 6,
  197.    9, 0, 7, 0, 11, 0, 10, 0, 10, 2,
  198.    2, 2, 2, 5, 0, 5, 0, 5, 0, 7,
  199.    0, 2, 2, 2, 0, 4, 0, 2, 0, 1,
  200.    0, 1, 1, 1, 1, 4, 1, 6, 0, 4,
  201.    3, 1, 4, 2, 2, 1, 4, 1, 2, 2,
  202.    2, 2, 1, 3, 3, 3, 3, 1, 3, 3,
  203.    1, 3, 3, 1, 3, 1, 3, 1, 5, 1,
  204.    3, 1, 0, 1, 1, 2, 2
  205. };
  206.  
  207. static short yydefact[] = {
  208.    51, 5, 63, 65, 64, 52, 6, 7, 69, 0, 0,
  209.    67, 0, 0, 55, 5, 5, 0, 5, 2, 9,
  210.    18, 10, 72, 78, 83, 88, 91, 94, 96, 98,
  211.    100, 102, 8, 0, 59, 0, 79, 80, 61, 0,
  212.    81, 0, 11, 0, 8, 82, 3, 5, 5, 5,
  213.    5, 51, 0, 19, 74, 75, 0, 0, 0, 0,
  214.    0, 0, 0, 0, 0, 0, 0, 0, 0, 57,
  215.    60, 0, 0, 62, 76, 0, 0, 14, 71, 12,
  216.    13, 16, 15, 17, 0, 51, 86, 87, 85, 84,
  217.    89, 90, 93, 92, 101, 95, 94, 97, 0, 73,
  218.    0, 70, 66, 51, 0, 56, 0, 0, 0, 0,
  219.    0, 45, 47, 0, 0, 51, 26, 51, 0, 21,
  220.    22, 23, 24, 0, 4, 0, 58, 0, 0, 0,
  221.    0, 59, 51, 51, 40, 41, 61, 0, 61, 42,
  222.    0, 43, 28, 20, 25, 27, 29, 99, 77, 68,
  223.    0, 0, 63, 0, 53, 54, 57, 0, 57, 0,
  224.    51, 32, 0, 0, 0, 49, 0, 0, 0, 51,
  225.    0, 59, 0, 46, 57, 48, 44, 30, 0, 0,
  226.    0, 59, 0, 51, 33, 38, 36, 0, 50, 0,
  227.    51, 51, 34, 31, 0, 0, 51, 39, 37, 0,
  228.    35, 0, 0, 0
  229. };
  230.  
  231. static short yydefgoto[] = {
  232.    202, 18, 19, 20, 21, 53, 117, 118, 119, 120, 121,
  233.    122, 170, 197, 192, 191, 123, 137, 139, 175, 1,
  234.    135, 22, 42, 102, 70, 73, 23, 35, 24, 74,
  235.     25, 26, 27, 28, 29, 30, 31, 32, 124, -1
  236. };
  237.  
  238. static short yypact[] = {
  239.    -32768, 250, -33, -32768, -32768, -32768, -32768, -32768, -32768, 409, 409,
  240.    -31, -25, 409, -32768, 349, 283, 409, 143, -32768, 68,
  241.    41, -32768, -32768, 75, 55, 73, 18, 29, 1, 7,
  242.    -32768, -32768, -32768, 409, 409, 409, -32768, -32768, 409, -2,
  243.    -32768, 63, -32768, 44, 45, -32768, -32768, 283, 283, 316,
  244.    283, -32768, 62, -32768, -32768, -32768, 409, 409, 409, 409,
  245.    409, 409, 409, 409, 409, 409, 409, 409, 49, 104,
  246.    -32768, 45, 76, 87, -32768, 88, 85, -32768, -32768, 114,
  247.    114, -32768, -32768, 114, 180, -32768, -32768, -32768, -32768, -32768,
  248.    -32768, -32768, -32768, -32768, -32768, -32768, 97, -32768, 74, -32768,
  249.    409, -32768, -32768, -32768, 409, -32768, 84, 89, 91, -8,
  250.    -8, -32768, 92, -8, -5, -32768, -32768, -32768, 213, -32768,
  251.    -32768, -32768, -32768, -8, 120, 409, -32768, 365, -15, 409,
  252.    409, 425, -32768, -32768, -32768, -32768, 409, 409, 409, -32768,
  253.    409, -32768, 120, 120, -32768, -32768, -32768, -32768, -32768, -32768,
  254.    93, 94, -4, 96, 120, 120, 104, 25, 104, 100,
  255.    -32768, -32768, 109, 387, -8, -32768, -8, -8, 180, -32768,
  256.    146, 409, 102, -32768, 104, -32768, -32768, 134, 180, 108,
  257.    110, 409, -8, -32768, -32768, -32768, -32768, 111, -32768, 180,
  258.    -32768, -32768, -32768, -32768, 180, 180, -32768, -32768, -32768, 180,
  259.    -32768, 154, 157, -32768
  260. };
  261.  
  262. static short yypgoto[] = {
  263.    -32768, -32768, 142, 3, -7, -32768, -118, 140, -32768, -32768, -32768,
  264.    -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -50,
  265.    -103, 31, -32768, -84, -126, -51, -32768, -32768, -32768, -81,
  266.    95, 56, 57, -41, 98, -63, -32768, -36, -1, -32768
  267. };
  268.  
  269. #define YYLAST          476
  270.  
  271. static short yytable[] = {
  272.    33, 146, 85, 75, 133, 99, 154, 133, 136, 44, 163,
  273.    140, 142, 39, 33, 45, 34, 33, 43, 40, 104,
  274.    147, 93, 94, 129, 96, 97, 97, 63, 95, 150,
  275.    67, 64, 69, 71, 72, 125, 14, 65, 141, 134,
  276.    80, 81, 134, 84, 34, 181, 33, 33, 33, 33,
  277.    178, 50, 82, 128, 50, 188, 158, 66, 68, 104,
  278.    185, 174, 148, 176, 177, 143, 77, 144, 75, 166,
  279.    76, 194, 165, 86, 167, 51, 198, 199, 51, 189,
  280.    83, 201, 155, 156, 97, 157, 52, 159, 78, 79,
  281.    183, 149, 57, 58, 59, 60, 48, 49, 100, 127,
  282.    75, 75, 75, 37, 38, 55, 56, 41, 61, 62,
  283.    169, 46, 87, 88, 89, 90, 101, 91, 92, 179,
  284.    103, 104, 105, 106, 50, 66, 126, 130, 151, 152,
  285.    71, 5, 131, 190, 132, 138, 171, 161, 162, 160,
  286.    195, 196, -1, 164, 168, 2, 200, 3, 180, 182,
  287.    4, 184, 186, 203, 187, 193, 204, 6, 7, 47,
  288.    54, 0, 173, 0, 98, 8, 0, 0, 0, 0,
  289.    71, 0, 0, 9, 10, 11, 12, 0, 0, 13,
  290.    71, 14, 2, 0, 3, 15, 16, 4, 0, 0,
  291.    0, 5, 0, 17, 0, 0, 107, 0, 108, 109,
  292.    110, 111, 8, 112, 113, 114, 115, 0, 0, 0,
  293.    9, 10, 11, 12, 0, 2, 13, 3, 0, 0,
  294.    4, 0, 0, 36, 0, 52, 0, 116, 0, 107,
  295.    17, 108, 109, 110, 111, 8, 112, 113, 114, 115,
  296.    0, 0, 0, 9, 10, 11, 12, 0, 0, 13,
  297.    0, 0, 2, 0, 3, 0, 36, 4, 52, 145,
  298.    116, 5, 0, 17, 6, 7, 0, 0, 0, 0,
  299.    0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
  300.    9, 10, 11, 12, 0, 2, 13, 3, 14, 0,
  301.    4, 0, 15, 16, 0, 0, 0, 6, 7, 0,
  302.    17, 0, 0, 0, 0, 8, 0, 0, 0, 0,
  303.    0, 0, 0, 9, 10, 11, 12, 0, 2, 13,
  304.    3, 14, 0, 4, 0, 15, 16, 0, 0, 0,
  305.    6, 7, 0, 17, 0, 0, 0, 0, 8, 0,
  306.    0, 0, 0, 0, 0, 0, 9, 10, 11, 12,
  307.    0, 2, 13, 3, 14, 0, 4, 0, 0, 36,
  308.    0, 0, 0, 6, 7, 0, 17, 2, 0, 3,
  309.    0, 8, 4, 0, 0, 0, 5, 0, 0, 9,
  310.    10, 11, 12, 0, 0, 13, 0, 8, 0, 2,
  311.    0, 3, 36, 0, 4, 9, 10, 11, 12, 17,
  312.    0, 13, 0, 0, 0, 0, 0, 0, 36, 8,
  313.    0, 2, 0, 3, 0, 17, 4, 9, 10, 11,
  314.    12, 0, 0, 13, 0, 0, 0, 153, 0, 3,
  315.    36, 8, 4, 0, 172, 0, 0, 17, 0, 9,
  316.    10, 11, 12, 0, 0, 13, 0, 8, 0, 0,
  317.    0, 0, 36, 0, 0, 9, 10, 11, 12, 17,
  318.    0, 13, 0, 0, 0, 0, 0, 0, 36, 0,
  319.    0, 0, 0, 0, 0, 17
  320. };
  321.  
  322. static short yycheck[] = {
  323.    1, 119, 52, 39, 12, 68, 132, 12, 111, 16, 14,
  324.    114, 115, 44, 15, 16, 49, 18, 15, 44, 35,
  325.    124, 63, 64, 105, 66, 67, 68, 10, 65, 45,
  326.    30, 14, 34, 35, 36, 86, 39, 9, 44, 48,
  327.    48, 49, 48, 51, 49, 172, 48, 49, 50, 51,
  328.    169, 11, 50, 104, 11, 182, 138, 29, 52, 35,
  329.    179, 165, 126, 167, 168, 116, 4, 118, 105, 45,
  330.    40, 190, 157, 12, 159, 35, 195, 196, 35, 183,
  331.    50, 200, 133, 134, 126, 137, 46, 139, 45, 45,
  332.    175, 128, 38, 39, 40, 41, 29, 30, 50, 101,
  333.    137, 138, 139, 9, 10, 31, 32, 13, 36, 37,
  334.    161, 17, 57, 58, 59, 60, 13, 61, 62, 170,
  335.    45, 35, 35, 39, 11, 29, 53, 44, 130, 131,
  336.    132, 12, 44, 184, 44, 44, 28, 45, 45, 141,
  337.    191, 192, 0, 48, 45, 3, 197, 5, 3, 48,
  338.    8, 18, 45, 0, 45, 45, 0, 15, 16, 18,
  339.    21, -1, 164, -1, 67, 23, -1, -1, -1, -1,
  340.    172, -1, -1, 31, 32, 33, 34, -1, -1, 37,
  341.    182, 39, 3, -1, 5, 43, 44, 8, -1, -1,
  342.    -1, 12, -1, 51, -1, -1, 17, -1, 19, 20,
  343.    21, 22, 23, 24, 25, 26, 27, -1, -1, -1,
  344.    31, 32, 33, 34, -1, 3, 37, 5, -1, -1,
  345.    8, -1, -1, 44, -1, 46, -1, 48, -1, 17,
  346.    51, 19, 20, 21, 22, 23, 24, 25, 26, 27,
  347.    -1, -1, -1, 31, 32, 33, 34, -1, -1, 37,
  348.    -1, -1, 3, -1, 5, -1, 44, 8, 46, 47,
  349.    48, 12, -1, 51, 15, 16, -1, -1, -1, -1,
  350.    -1, -1, 23, -1, -1, -1, -1, -1, -1, -1,
  351.    31, 32, 33, 34, -1, 3, 37, 5, 39, -1,
  352.    8, -1, 43, 44, -1, -1, -1, 15, 16, -1,
  353.    51, -1, -1, -1, -1, 23, -1, -1, -1, -1,
  354.    -1, -1, -1, 31, 32, 33, 34, -1, 3, 37,
  355.    5, 39, -1, 8, -1, 43, 44, -1, -1, -1,
  356.    15, 16, -1, 51, -1, -1, -1, -1, 23, -1,
  357.    -1, -1, -1, -1, -1, -1, 31, 32, 33, 34,
  358.    -1, 3, 37, 5, 39, -1, 8, -1, -1, 44,
  359.    -1, -1, -1, 15, 16, -1, 51, 3, -1, 5,
  360.    -1, 23, 8, -1, -1, -1, 12, -1, -1, 31,
  361.    32, 33, 34, -1, -1, 37, -1, 23, -1, 3,
  362.    -1, 5, 44, -1, 8, 31, 32, 33, 34, 51,
  363.    -1, 37, -1, -1, -1, -1, -1, -1, 44, 23,
  364.    -1, 3, -1, 5, -1, 51, 8, 31, 32, 33,
  365.    34, -1, -1, 37, -1, -1, -1, 3, -1, 5,
  366.    44, 23, 8, -1, 48, -1, -1, 51, -1, 31,
  367.    32, 33, 34, -1, -1, 37, -1, 23, -1, -1,
  368.    -1, -1, 44, -1, -1, 31, 32, 33, 34, 51,
  369.    -1, 37, -1, -1, -1, -1, -1, -1, 44, -1,
  370.    -1, -1, -1, -1, -1, 51
  371. };
  372. #define YYPURE 1
  373.  
  374. /*
  375.  * Skeleton output parser for bison,
  376.  * copyright (C) 1984 Bob Corbett and Richard Stallman 
  377.  *
  378.  * Permission is granted to anyone to make or distribute verbatim copies of this
  379.  * program provided that the copyright notice and this permission notice are
  380.  * preserved; and provided that the recipient is not asked to waive or limit his
  381.  * right to redistribute copies as permitted by this permission notice; and
  382.  * provided that anyone possessing an executable copy is granted access to copy the
  383.  * source code, in machine-readable form, in some reasonable manner. 
  384.  *
  385.  * Permission is granted to distribute derived works or enhanced versions of this
  386.  * program under the above conditions with the additional condition that the
  387.  * entire derivative or enhanced work must be covered by a permission notice
  388.  * identical to this one. 
  389.  *
  390.  * Anything distributed as part of a package containing portions derived from
  391.  * this program, which cannot in current practice perform its function
  392.  * usefully in the absense of what was derived directly from this program, is
  393.  * to be considered as forming, together with the latter, a single work
  394.  * derived from this program, which must be entirely covered by a permission
  395.  * notice identical to this one in order for distribution of the package to be
  396.  * permitted. 
  397.  *
  398.  * In other words, you are welcome to use, share and improve this program.
  399.  * You are forbidden to forbid anyone else to use, share and improve what you
  400.  * give them.   Help stamp out software-hoarding!  
  401.  */
  402.  
  403. /*
  404.  * This is the parser code that is written into each bison parser when the
  405.  * %semantic_parser declaration is not specified in the grammar. It was
  406.  * written by Richard Stallman by simplifying the hairy parser used when
  407.  * %semantic_parser is specified.  
  408.  */
  409.  
  410. /*
  411.  * Note: there must be only one dollar sign in this file. It is replaced by
  412.  * the list of actions, each action as one case of the switch.  
  413.  */
  414.  
  415. #include <malloc.h>
  416. #include <string.h>
  417.  
  418. #define yyerrok         (yyerrstatus = 0)
  419. #define yyclearin       (yychar = YYEMPTY)
  420. #define YYEMPTY         -2
  421. #define YYEOF           0
  422. #define YYFAIL          goto yyerrlab;
  423.  
  424. #define YYTERROR        1
  425.  
  426. #ifndef YYIMPURE
  427. #define YYLEX           yylex()
  428. int yylex(void);                       /* WG */
  429. #endif
  430.  
  431. #ifndef YYPURE
  432. #define YYLEX           yylex(&yylval, &yylloc)
  433. int yylex(int, int);                   /* WG */
  434. #endif
  435.  
  436. /* If nonreentrant, generate the variables here */
  437.  
  438. #ifndef YYIMPURE
  439.  
  440. int yychar;                            /* the lookahead symbol                */
  441. YYSTYPE yylval;                        /* the semantic value of the           */
  442.                                        /* lookahead symbol                    */
  443.  
  444. YYLTYPE yylloc;                        /* location data for the lookahead     */
  445. /* symbol                              */
  446.  
  447. int yydebug = 0;                       /* nonzero means print parse trace     */
  448.  
  449. #endif
  450.  
  451.  
  452. /* YYMAXDEPTH indicates the initial size of the parser's stacks        */
  453.  
  454. #ifndef YYMAXDEPTH
  455. #define YYMAXDEPTH 200
  456. #endif
  457.  
  458. /*
  459.  * YYMAXLIMIT is the maximum size the stacks can grow to (effective only if the built-in stack extension method is used).  
  460.  */
  461.  
  462. #ifndef YYMAXLIMIT
  463. #define YYMAXLIMIT 10000
  464. #endif
  465.  
  466.  
  467. int yyparse()
  468. {
  469.    register int yystate;
  470.    register int yyn;
  471.    register short *yyssp;
  472.    register YYSTYPE *yyvsp;
  473.    void yyerror(char *,...);           /* WG  [ ',...' - added ADE ] */
  474.    YYLTYPE *yylsp;
  475.    int yyerrstatus;                    /* number of tokens to shift before error messages enabled */
  476.    int yychar1;                        /* lookahead token as an internal (translated) token number */
  477.  
  478.    short yyssa[YYMAXDEPTH];            /* the state stack                     */
  479.    YYSTYPE yyvsa[YYMAXDEPTH];          /* the semantic value stack            */
  480.    YYLTYPE yylsa[YYMAXDEPTH];          /* the location stack                  */
  481.  
  482.    short *yyss = yyssa;                /* refer to the stacks thru separate pointers */
  483.    YYSTYPE *yyvs = yyvsa;              /* to allow yyoverflow to reallocate them elsewhere */
  484.    YYLTYPE *yyls = yylsa;
  485.  
  486.    int yymaxdepth = YYMAXDEPTH;
  487.  
  488. #ifndef YYPURE
  489.  
  490.    int yychar;
  491.    YYSTYPE yylval;
  492.    YYLTYPE yylloc;
  493.  
  494.    extern int yydebug;
  495.  
  496. #endif
  497.  
  498.  
  499.    YYSTYPE yyval;                      /* the variable used to return         */
  500.                                        /* semantic values from the action     */
  501.                                        /* routines                            */
  502.    int yylen;
  503.  
  504.    if (yydebug)
  505.       fprintf(stderr, "Starting parse\n");
  506.  
  507.    yystate = 0;
  508.    yyerrstatus = 0;
  509.    yychar = YYEMPTY;                   /* Cause a token to be read.  */
  510.  
  511.    /*
  512.     * Initialize stack pointers. Waste one element of value and location
  513.     * stack so that they stay on the same level as the state stack.  
  514.     */
  515.  
  516.    yyssp = yyss - 1;
  517.    yyvsp = yyvs;
  518.    yylsp = yyls;
  519.  
  520.    /* Push a new state, which is found in  yystate
  521.     *
  522.     * In all cases, when you get here, the value and location stacks have
  523.     * just been pushed. so pushing a state here evens the stacks.  
  524.     */
  525. yynewstate:
  526.  
  527.    *++yyssp = yystate;
  528.  
  529.    if (yyssp >= yyss + yymaxdepth - 1)
  530.    {
  531.       /* Give user a chance to reallocate the stack */
  532.       /* Use copies of these so that the &'s don't force the real ones into memory. */
  533.       YYSTYPE *yyvs1 = yyvs;
  534.       YYLTYPE *yyls1 = yyls;
  535.       short *yyss1 = yyss;
  536.  
  537.       /* Get the current used size of the three stacks, in elements.  */
  538.       int size = yyssp - yyss + 1;
  539.  
  540. #ifdef yyoverflow
  541.       /*
  542.        * Each stack pointer address is followed by the size of the data in use in that stack, in bytes.  
  543.        */
  544.       yyoverflow("parser stack overflow", &yyss1, size * sizeof(*yyssp),
  545.                  &yyvs1, size * sizeof(*yyvsp), &yyls1, size * sizeof(*yylsp),
  546.                  &yymaxdepth);
  547.  
  548.       yyss = yyss1;
  549.       yyvs = yyvs1;
  550.       yyls = yyls1;
  551. #else
  552.       /* Extend the stack our own way.  */
  553.         if (yymaxdepth >= YYMAXLIMIT)
  554.          yyerror("parser stack overflow");
  555.       yymaxdepth *= 2;
  556.       if (yymaxdepth > YYMAXLIMIT)
  557.          yymaxdepth = YYMAXLIMIT;
  558.       yyss = (short *) alloca(yymaxdepth * sizeof(*yyssp));
  559.       memcpy((char *) yyss, (char *) yyss1, size * sizeof(*yyssp));     /* WG */
  560.       yyls = (YYLTYPE *) alloca(yymaxdepth * sizeof(*yylsp));
  561.       memcpy((char *) yyls, (char *) yyls1, size * sizeof(*yylsp));     /* WG */
  562.       yyvs = (YYSTYPE *) alloca(yymaxdepth * sizeof(*yyvsp));
  563.       memcpy((char *) yyvs, (char *) yyvs1, size * sizeof(*yyvsp));     /* WG */
  564. #endif
  565.  
  566.       yyssp = yyss + size - 1;
  567.       yylsp = yyls + size - 1;
  568.       yyvsp = yyvs + size - 1;
  569.  
  570.       if (yydebug)
  571.          fprintf(stderr, "Stack size increased to %d\n", yymaxdepth);
  572.  
  573.       if (yyssp >= yyss + yymaxdepth - 1)
  574.          YYERROR;
  575.    }
  576.  
  577.    if (yydebug)
  578.       fprintf(stderr, "Entering state %d\n", yystate);
  579.  
  580.    /* Do appropriate processing given the current state.  */
  581.    /* Read a lookahead token if we need one and don't already have one.  */
  582. yyresume:
  583.  
  584.    /* First try to decide what to do without reference to lookahead token.  */
  585.  
  586.    yyn = (int) yypact[yystate];        /* WG */
  587.    if (yyn == YYFLAG)
  588.       goto yydefault;
  589.  
  590.    /* Not known => get a lookahead token if don't already have one.  */
  591.  
  592.    /*
  593.     * yychar is either YYEMPTY or YYEOF or a valid token in external form.  
  594.     */
  595.  
  596.    if (yychar == YYEMPTY)
  597.    {
  598.       yychar = YYLEX;
  599.    }
  600.  
  601.    /* Convert token to internal form (in yychar1) for indexing tables with */
  602.  
  603.    if (yychar <= 0)                    /* This means end of input. */
  604.    {
  605.       yychar1 = 0;
  606.       yychar = YYEOF;                  /* Don't call YYLEX any more */
  607.  
  608.       if (yydebug)
  609.          fprintf(stderr, "Now at end of input.\n");
  610.    }
  611.    else
  612.    {
  613.       yychar1 = YYTRANSLATE(yychar);
  614.  
  615.       if (yydebug)
  616.          fprintf(stderr, "Parsing next token; it is %d (%s)\n", yychar, yytname[yychar1]);
  617.    }
  618.  
  619.    yyn += yychar1;
  620.    if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
  621.       goto yydefault;
  622.  
  623.    yyn = yytable[yyn];
  624.  
  625.    /*
  626.     * yyn is what to do for this token type in this state.
  627.     *   Negative => reduce, -yyn is rule number.
  628.     *   Positive => shift, yyn is new state. New state is final state
  629.     *     don't bother to shift, just return success.
  630.     *   0, or most negative number => error.  
  631.     */
  632.  
  633.    if (yyn < 0)
  634.    {
  635.       if (yyn == (int) YYFLAG)         /* WG */
  636.          goto yyerrlab;
  637.       yyn = -yyn;
  638.       goto yyreduce;
  639.    }
  640.    else if (yyn == 0)
  641.       goto yyerrlab;
  642.  
  643.    if (yyn == YYFINAL)
  644.       YYACCEPT;
  645.  
  646.    /* Shift the lookahead token.  */
  647.  
  648.    if (yydebug)
  649.       fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
  650.  
  651.    /* Discard the token being shifted unless it is eof.  */
  652.    if (yychar != YYEOF)
  653.       yychar = YYEMPTY;
  654.  
  655.    *++yyvsp = yylval;
  656.    *++yylsp = yylloc;
  657.  
  658.    /* count tokens shifted since error; after three, turn off error status.  */
  659.    if (yyerrstatus)
  660.       yyerrstatus--;
  661.  
  662.    yystate = yyn;
  663.    goto yynewstate;
  664.  
  665.    /* Do the default action for the current state.  */
  666. yydefault:
  667.  
  668.    yyn = yydefact[yystate];
  669.    if (yyn == 0)
  670.       goto yyerrlab;
  671.  
  672.    /* Do a reduction.  yyn is the number of a rule to reduce with.  */
  673. yyreduce:
  674.    yylen = yyr2[yyn];
  675.    yyval = yyvsp[1 - yylen];           /* implement default value of the action */
  676.  
  677.    if (yydebug)
  678.    {
  679.       if (yylen == 1)
  680.          fprintf(stderr, "Reducing 1 value via line %d, ", yyrline[yyn]);
  681.       else
  682.          fprintf(stderr, "Reducing %d values via line %d, ", yylen, yyrline[yyn]);
  683.    }
  684.    /* the action file follows */
  685.  
  686.    switch (yyn)
  687.    {
  688.    case 1:
  689.       {
  690.          expression_value = yyvsp[0].nodeval;
  691.          break;
  692.       }
  693.    case 2:
  694.       {
  695.          yyval.nodeval = node(yyvsp[0].nodeval, Node_rule_list, (NODE *) NULL);
  696.          break;
  697.       }
  698.    case 3:
  699.       {
  700.          yyval.nodeval = append_right(yyvsp[-1].nodeval, node(yyvsp[0].nodeval, Node_rule_list, (NODE *) NULL));
  701.          break;
  702.       }
  703.    case 4:
  704.       {
  705.          ++patterns;
  706.          ++actions;
  707.          yyval.nodeval = node(yyvsp[-3].nodeval, Node_rule_node, yyvsp[-2].nodeval);
  708.          break;
  709.       }
  710.    case 5:
  711.       {
  712.          yyval.nodeval = NULL;
  713.          break;
  714.       }
  715.    case 6:
  716.       {
  717.          --patterns;
  718.          --actions;
  719.          yyval.nodeval = node((NODE *) NULL, Node_K_BEGIN, (NODE *) NULL);
  720.          break;
  721.       }
  722.    case 7:
  723.       {
  724.          yyval.nodeval = node((NODE *) NULL, Node_K_END, (NODE *) NULL);
  725.          break;
  726.       }
  727.    case 8:
  728.       {
  729.          yyval.nodeval = yyvsp[0].nodeval;
  730.          break;
  731.       }
  732.    case 9:
  733.       {
  734.          yyval.nodeval = yyvsp[0].nodeval;
  735.          break;
  736.       }
  737.    case 10:
  738.       {
  739.          yyval.nodeval = node(node(make_number((AWKNUM) 0), Node_field_spec, (NODE *) NULL), Node_match, yyvsp[0].nodeval);
  740.          break;
  741.       }
  742.    case 11:
  743.       {
  744.          yyval.nodeval = node(yyvsp[0].nodeval, Node_not, (NODE *) NULL);
  745.          break;
  746.       }
  747.    case 12:
  748.       {
  749.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_and, yyvsp[0].nodeval);
  750.          break;
  751.       }
  752.    case 13:
  753.       {
  754.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_or, yyvsp[0].nodeval);
  755.          break;
  756.       }
  757.    case 14:
  758.       {
  759.          yyval.nodeval = yyvsp[-1].nodeval;
  760.          want_concat_token = 0;
  761.          break;
  762.       }
  763.    case 15:
  764.       {
  765.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_match, yyvsp[0].nodeval);
  766.          break;
  767.       }
  768.    case 16:
  769.       {
  770.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_match, yyvsp[0].nodeval);
  771.          break;
  772.       }
  773.    case 17:
  774.       {
  775.          yyval.nodeval = mkrangenode(node(yyvsp[-2].nodeval, Node_cond_pair, yyvsp[0].nodeval));
  776.          break;
  777.       }
  778.    case 18:
  779.       {
  780.          --actions;
  781.          yyval.nodeval = NULL;
  782.          break;
  783.       }
  784.    case 19:
  785.       {
  786.          yyval.nodeval = yyvsp[0].nodeval;
  787.          break;
  788.       }
  789.    case 20:
  790.       {
  791.          yyval.nodeval = yyvsp[-1].nodeval;
  792.          break;
  793.       }
  794.    case 21:
  795.       {
  796.          yyval.nodeval = yyvsp[0].nodeval;
  797.          break;
  798.       }
  799.    case 22:
  800.       {
  801.          yyval.nodeval = yyvsp[0].nodeval;
  802.          break;
  803.       }
  804.    case 23:
  805.       {
  806.          yyval.nodeval = yyvsp[0].nodeval;
  807.          break;
  808.       }
  809.    case 24:
  810.       {
  811.          yyval.nodeval = yyvsp[0].nodeval;
  812.          break;
  813.       }
  814.    case 25:
  815.       {
  816.          yyval.nodeval = node(yyvsp[-1].nodeval, Node_statement_list, (NODE *) NULL);
  817.          break;
  818.       }
  819.    case 26:
  820.       {
  821.          yyval.nodeval = node(yyvsp[0].nodeval, Node_statement_list, (NODE *) NULL);
  822.          break;
  823.       }
  824.    case 27:
  825.       {
  826.          yyval.nodeval = append_right(yyvsp[-1].nodeval, node(yyvsp[0].nodeval, Node_statement_list, (NODE *) NULL));
  827.          break;
  828.       }
  829.    case 28:
  830.       {
  831.          yyval.nodeval = (NODE *) NULL;
  832.          break;
  833.       }
  834.    case 29:
  835.       {
  836.          yyval.nodeval = node(yyvsp[-1].nodeval, Node_statement_list, (NODE *) NULL);
  837.          break;
  838.       }
  839.    case 30:
  840.       {
  841.          yyval.nodeval = node(yyvsp[-3].nodeval, Node_K_if, node(yyvsp[0].nodeval, Node_if_branches, (NODE *) NULL));
  842.          break;
  843.       }
  844.    case 31:
  845.       {
  846.          yyval.nodeval = node(yyvsp[-6].nodeval, Node_K_if, node(yyvsp[-3].nodeval, Node_if_branches, yyvsp[0].nodeval));
  847.          break;
  848.       }
  849.    case 32:
  850.       {
  851.          want_concat_token = 0;
  852.          break;
  853.       }
  854.    case 33:
  855.       {
  856.          yyval.nodeval = node(yyvsp[-4].nodeval, Node_K_while, yyvsp[0].nodeval);
  857.          break;
  858.       }
  859.    case 34:
  860.       {
  861.          want_concat_token = 0;
  862.          break;
  863.       }
  864.    case 35:
  865.       {
  866.          yyval.nodeval = node(yyvsp[0].nodeval, Node_K_for, (NODE *) make_for_loop(yyvsp[-8].nodeval, yyvsp[-6].nodeval, yyvsp[-4].nodeval));
  867.          break;
  868.       }
  869.    case 36:
  870.       {
  871.          want_concat_token = 0;
  872.          break;
  873.       }
  874.    case 37:
  875.       {
  876.          yyval.nodeval = node(yyvsp[0].nodeval, Node_K_for,
  877.             (NODE *) make_for_loop(yyvsp[-7].nodeval, (NODE *) NULL, yyvsp[-4].nodeval));
  878.          break;
  879.       }
  880.    case 38:
  881.       {
  882.          want_concat_token = 0;
  883.          break;
  884.       }
  885.    case 39:
  886.       {
  887.          yyval.nodeval = node(yyvsp[0].nodeval, Node_K_arrayfor,
  888.             (NODE *) make_for_loop(variable(yyvsp[-7].sval), (NODE *) NULL, variable(yyvsp[-4].sval)));
  889.          break;
  890.       }
  891.    case 40:
  892.       {
  893.          yyval.nodeval = node((NODE *) NULL, Node_K_break, (NODE *) NULL);
  894.          break;
  895.       }
  896.    case 41:
  897.       {
  898.          yyval.nodeval = node((NODE *) NULL, Node_K_continue, (NODE *) NULL);
  899.          break;
  900.       }
  901.    case 42:
  902.       {
  903.          yyval.nodeval = node((NODE *) NULL, Node_K_next, (NODE *) NULL);
  904.          break;
  905.       }
  906.    case 43:
  907.       {
  908.          yyval.nodeval = node((NODE *) NULL, Node_K_exit, (NODE *) NULL);
  909.          break;
  910.       }
  911.    case 44:
  912.       {
  913.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_K_exit, (NODE *) NULL);
  914.          break;
  915.       }
  916.    case 45:
  917.       {
  918.          ++want_redirect;
  919.          want_concat_token = 0;
  920.          break;
  921.       }
  922.    case 46:
  923.       {
  924.          want_redirect = 0;
  925.          /* $4->lnode = NULL; */
  926.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_K_print, yyvsp[-1].nodeval);
  927.          break;
  928.       }
  929.    case 47:
  930.       {
  931.          ++want_redirect;
  932.          want_concat_token = 0;
  933.          break;
  934.       }
  935.    case 48:
  936.       {
  937.          want_redirect = 0;
  938.          /* $4->lnode = NULL; */
  939.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_K_printf, yyvsp[-1].nodeval);
  940.          break;
  941.       }
  942.    case 49:
  943.       {
  944.          ++want_redirect;
  945.          want_concat_token = 0;
  946.          break;
  947.       }
  948.    case 50:
  949.       {
  950.          want_redirect = 0;
  951.          yyval.nodeval = node(yyvsp[-4].nodeval, Node_K_printf, yyvsp[-1].nodeval);
  952.          break;
  953.       }
  954.    case 52:
  955.       {
  956.          yyval.nodetypeval = Node_illegal;
  957.          break;
  958.       }
  959.    case 53:
  960.       {
  961.          yyval.nodetypeval = Node_illegal;
  962.          break;
  963.       }
  964.    case 54:
  965.       {
  966.          yyval.nodetypeval = Node_illegal;
  967.          break;
  968.       }
  969.    case 55:
  970.       {
  971.          ++want_regexp;
  972.          break;
  973.       }
  974.    case 56:
  975.       {
  976.          want_regexp = 0;
  977.          yyval.nodeval = make_regex(yyvsp[-1].sval);
  978.          break;
  979.       }
  980.    case 57:
  981.       {
  982.          yyval.nodeval = NULL; /* node (NULL, Node_redirect_nil, NULL); */ ;
  983.          break;
  984.       }
  985.    case 58:
  986.       {
  987.          yyval.nodeval = node(yyvsp[0].nodeval, yyvsp[-1].nodetypeval, (NODE *) NULL);
  988.          break;
  989.       }
  990.    case 59:
  991.       {
  992.          yyval.nodeval = NULL; /* node(NULL, Node_builtin, NULL); */ ;
  993.          break;
  994.       }
  995.    case 60:
  996.       {
  997.          yyval.nodeval = yyvsp[0].nodeval;
  998.          break;
  999.       }
  1000.    case 61:
  1001.       {
  1002.          yyval.nodeval = NULL;
  1003.          break;
  1004.       }
  1005.    case 62:
  1006.       {
  1007.          yyval.nodeval = yyvsp[0].nodeval;
  1008.          break;
  1009.       }
  1010.    case 63:
  1011.       {
  1012.          yyval.nodeval = variable(yyvsp[0].sval);
  1013.          break;
  1014.       }
  1015.    case 64:
  1016.       {
  1017.          yyval.nodeval = make_number(yyvsp[0].fval);
  1018.          break;
  1019.       }
  1020.    case 65:
  1021.       {
  1022.          yyval.nodeval = make_string(yyvsp[0].sval, -1);
  1023.          break;
  1024.       }
  1025.    case 66:
  1026.       {
  1027.          ++want_concat_token;
  1028.          yyval.nodeval = snode(yyvsp[-1].nodeval, Node_builtin, yyvsp[-3].ptrval);
  1029.          break;
  1030.       }
  1031.    case 67:
  1032.       {
  1033.          ++want_concat_token;
  1034.          yyval.nodeval = snode((NODE *) NULL, Node_builtin, yyvsp[0].ptrval);
  1035.          break;
  1036.       }
  1037.    case 68:
  1038.       {
  1039.          want_concat_token;
  1040.          yyval.nodeval = snode(node(yyvsp[-3].nodeval, Node_expression_list, yyvsp[-1].nodeval), Node_builtin, yyvsp[-5].ptrval);
  1041.          break;
  1042.       }
  1043.    case 69:
  1044.       {
  1045.          ++want_redirect;
  1046.          break;
  1047.       }
  1048.    case 70:
  1049.       {
  1050.          want_redirect = 0;
  1051.          yyval.nodeval = node(yyvsp[-1].nodeval, Node_K_getline, yyvsp[0].nodeval);
  1052.          break;
  1053.       }
  1054.    case 71:
  1055.       {
  1056.          yyval.nodeval = yyvsp[-1].nodeval;
  1057.          break;
  1058.       }
  1059.    case 72:
  1060.       {
  1061.          yyval.nodeval = yyvsp[0].nodeval;
  1062.          break;
  1063.       }
  1064.    case 73:
  1065.       {
  1066.          yyval.nodeval = node(variable(yyvsp[-3].sval), Node_subscript, yyvsp[-1].nodeval);
  1067.          break;
  1068.       }
  1069.    case 74:
  1070.       {
  1071.          yyval.nodeval = node(yyvsp[-1].nodeval, Node_postincrement, (NODE *) NULL);
  1072.          break;
  1073.       }
  1074.    case 75:
  1075.       {
  1076.          yyval.nodeval = node(yyvsp[-1].nodeval, Node_postdecrement, (NODE *) NULL);
  1077.          break;
  1078.       }
  1079.    case 76:
  1080.       {
  1081.          yyval.nodeval = node(yyvsp[0].nodeval, Node_expression_list, (NODE *) NULL);
  1082.          break;
  1083.       }
  1084.    case 77:
  1085.       {
  1086.          yyval.nodeval = append_right(yyvsp[-3].nodeval,
  1087.                                       node(yyvsp[0].nodeval, Node_expression_list, (NODE *) NULL));
  1088.          break;
  1089.       }
  1090.    case 78:
  1091.       {
  1092.          yyval.nodeval = yyvsp[0].nodeval;
  1093.          break;
  1094.       }
  1095.    case 79:
  1096.       {
  1097.          yyval.nodeval = node(yyvsp[0].nodeval, Node_preincrement, (NODE *) NULL);
  1098.          break;
  1099.       }
  1100.    case 80:
  1101.       {
  1102.          yyval.nodeval = node(yyvsp[0].nodeval, Node_predecrement, (NODE *) NULL);
  1103.          break;
  1104.       }
  1105.    case 81:
  1106.       {
  1107.          yyval.nodeval = node(yyvsp[0].nodeval, Node_unary_minus, (NODE *) NULL);
  1108.          break;
  1109.       }
  1110.    case 82:
  1111.       {
  1112.          yyval.nodeval = node(yyvsp[0].nodeval, Node_field_spec, (NODE *) NULL);
  1113.          break;
  1114.       }
  1115.    case 83:
  1116.       {
  1117.          yyval.nodeval = yyvsp[0].nodeval;
  1118.          break;
  1119.       }
  1120.    case 84:
  1121.       {
  1122.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_pow, yyvsp[0].nodeval);
  1123.          break;
  1124.       }
  1125.    case 85:
  1126.       {
  1127.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_mod, yyvsp[0].nodeval);
  1128.          break;
  1129.       }
  1130.    case 86:
  1131.       {
  1132.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_times, yyvsp[0].nodeval);
  1133.          break;
  1134.       }
  1135.    case 87:
  1136.       {
  1137.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_quotient, yyvsp[0].nodeval);
  1138.          break;
  1139.       }
  1140.    case 88:
  1141.       {
  1142.          yyval.nodeval = yyvsp[0].nodeval;
  1143.          break;
  1144.       }
  1145.    case 89:
  1146.       {
  1147.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_plus, yyvsp[0].nodeval);
  1148.          break;
  1149.       }
  1150.    case 90:
  1151.       {
  1152.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_minus, yyvsp[0].nodeval);
  1153.          break;
  1154.       }
  1155.    case 91:
  1156.       {
  1157.          yyval.nodeval = yyvsp[0].nodeval;
  1158.          break;
  1159.       }
  1160.    case 92:
  1161.       {
  1162.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_concat, yyvsp[0].nodeval);
  1163.          break;
  1164.       }
  1165.    case 93:
  1166.       {
  1167.          yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-1].nodetypeval, yyvsp[0].nodeval);
  1168.          break;
  1169.       }
  1170.    case 94:
  1171.       {
  1172.          yyval.nodeval = yyvsp[0].nodeval;
  1173.          break;
  1174.       }
  1175.    case 95:
  1176.       {
  1177.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_and, yyvsp[0].nodeval);
  1178.          break;
  1179.       }
  1180.    case 96:
  1181.       {
  1182.          yyval.nodeval = yyvsp[0].nodeval;
  1183.          break;
  1184.       }
  1185.    case 97:
  1186.       {
  1187.          yyval.nodeval = node(yyvsp[-2].nodeval, Node_or, yyvsp[0].nodeval);
  1188.          break;
  1189.       }
  1190.    case 98:
  1191.       {
  1192.          yyval.nodeval = yyvsp[0].nodeval;
  1193.          break;
  1194.       }
  1195.    case 99:
  1196.       {
  1197.          yyval.nodeval = node(yyvsp[-4].nodeval, Node_cond_exp, node(yyvsp[-2].nodeval, Node_illegal, yyvsp[0].nodeval));
  1198.          break;
  1199.       }
  1200.    case 100:
  1201.       {
  1202.          yyval.nodeval = yyvsp[0].nodeval;
  1203.          break;
  1204.       }
  1205.    case 101:
  1206.       {
  1207.          yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-1].nodetypeval, yyvsp[0].nodeval);
  1208.          break;
  1209.       }
  1210.    case 102:
  1211.       {
  1212.          yyval.nodeval = yyvsp[0].nodeval;
  1213.          break;
  1214.       }
  1215.    case 103:
  1216.       {
  1217.          yyval.nodetypeval = Node_illegal;
  1218.          break;
  1219.       }
  1220.    }
  1221.    /* the action file gets copied in in place of this dollarsign */
  1222.    /* the action file ends */
  1223.    yyvsp -= yylen;
  1224.    yylsp -= yylen;
  1225.    yyssp -= yylen;
  1226.  
  1227.    if (yydebug)
  1228.    {
  1229.       short *ssp1 = yyss - 1;
  1230.  
  1231.       fprintf(stderr, "state stack now", yyssp - yyss);
  1232.       while (ssp1 != yyssp)
  1233.          fprintf(stderr, " %d", *++ssp1);
  1234.       fprintf(stderr, "\n");
  1235.    }
  1236.  
  1237.    *++yyvsp = yyval;
  1238.  
  1239.    yylsp++;
  1240.    if (yylen == 0)
  1241.    {
  1242.       yylsp->first_line = yylloc.first_line;
  1243.       yylsp->first_column = yylloc.first_column;
  1244.       yylsp->last_line = (yylsp - 1)->last_line;
  1245.       yylsp->last_column = (yylsp - 1)->last_column;
  1246.       yylsp->text = 0;
  1247.    }
  1248.    else
  1249.    {
  1250.       yylsp->last_line = (yylsp + yylen - 1)->last_line;
  1251.       yylsp->last_column = (yylsp + yylen - 1)->last_column;
  1252.    }
  1253.  
  1254.    /*
  1255.     * Now "shift" the result of the reduction. Determine what state that goes to,
  1256.     * based on the state we popped back to and the rule number reduced by.  
  1257.     */
  1258.  
  1259.    yyn = yyr1[yyn];
  1260.  
  1261.    yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
  1262.    if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
  1263.       yystate = yytable[yystate];
  1264.    else
  1265.       yystate = yydefgoto[yyn - YYNTBASE];
  1266.  
  1267.    goto yynewstate;
  1268.  
  1269. yyerrlab:                             /* here on detecting error */
  1270.  
  1271.    if (!yyerrstatus)
  1272.       /* If not already recovering from an error, report this error.  */
  1273.    {
  1274.       yyerror("parse error");
  1275.    }
  1276.  
  1277.    if (yyerrstatus == 3)
  1278.    {
  1279.       /* if just tried and failed to reuse lookahead token after an error, discard it.  */
  1280.  
  1281.       /* return failure if at end of input */
  1282.       if (yychar == YYEOF)
  1283.          YYERROR;
  1284.  
  1285.       if (yydebug)
  1286.          fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
  1287.  
  1288.       yychar = YYEMPTY;
  1289.    }
  1290.  
  1291.    /*
  1292.     * Else will try to reuse lookahead token after shifting the error token.  
  1293.     */
  1294.  
  1295.    yyerrstatus = 3;                    /* Each real token shifted decrements this */
  1296.  
  1297.    goto yyerrhandle;
  1298.  
  1299. yyerrdefault:                         /* current state does not do anything special for the error token. */
  1300.  
  1301.    yyn = yydefact[yystate];            /* If its default is to accept any token, ok.  Otherwise pop it. */
  1302.    if (yyn)
  1303.       goto yydefault;
  1304.  
  1305. yyerrpop:                             /* pop the current state because it cannot handle the error token */
  1306.  
  1307.    if (yyssp == yyss)
  1308.       YYERROR;
  1309.    yyvsp--;
  1310.    yylsp--;
  1311.    yystate = *--yyssp;
  1312.  
  1313.    if (yydebug)
  1314.    {
  1315.       short *ssp1 = yyss - 1;
  1316.       fprintf(stderr, "Error: state stack now", yyssp - yyss);
  1317.       while (ssp1 != yyssp)
  1318.          fprintf(stderr, " %d", *++ssp1);
  1319.       fprintf(stderr, "\n");
  1320.    }
  1321.  
  1322. yyerrhandle:
  1323.  
  1324.    yyn = yypact[yystate];
  1325.    if (yyn == (int) YYFLAG)            /* WG */
  1326.       goto yyerrdefault;
  1327.  
  1328.    yyn += YYTERROR;
  1329.    if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
  1330.       goto yyerrdefault;
  1331.  
  1332.    yyn = yytable[yyn];
  1333.    if (yyn < 0)
  1334.    {
  1335.       if (yyn == YYFLAG)
  1336.          goto yyerrpop;
  1337.       yyn = -yyn;
  1338.       goto yyreduce;
  1339.    }
  1340.    else if (yyn == 0)
  1341.       goto yyerrpop;
  1342.  
  1343.    if (yyn == YYFINAL)
  1344.       YYACCEPT;
  1345.  
  1346.    if (yydebug)
  1347.       fprintf(stderr, "Shifting error token, ");
  1348.  
  1349.    *++yyvsp = yylval;
  1350.    *++yylsp = yylloc;
  1351.  
  1352.    yystate = yyn;
  1353.    goto yynewstate;
  1354. }
  1355.  
  1356. struct token
  1357. {
  1358.    char *operator;
  1359.    NODETYPE value;
  1360.    int class;
  1361.    NODE *(*ptr) ();
  1362. };
  1363.  
  1364. #ifndef NULL
  1365.  
  1366. #define NULL 0
  1367.  
  1368. #endif
  1369.  
  1370. NODE *do_atan2(), *do_close(), *do_cos(), *do_exp(), *do_getline(),
  1371.      *do_gsub(), *do_index(), *do_length(), *do_log(), *do_match(),
  1372.      *do_rand(), *do_sin(), *do_sqrt(),
  1373.      *do_srand(), *do_sprintf(), *do_sub(), *do_substr(), *do_system(),
  1374.      *do_split(), *do_int();
  1375.  
  1376. /* Special functions for debugging */
  1377. #ifndef FAST
  1378. NODE *do_prvars(), *do_bp();
  1379. #endif
  1380.  
  1381. /* Tokentab is sorted ascii ascending order, so it can be binary searched. */
  1382. /* (later.  Right now its just sort of linear search (SLOW!!) */
  1383.  
  1384. #define END(s) (s-1 + sizeof(s)/sizeof(s[0]))
  1385.  
  1386. static struct token tokentab[] = {
  1387.    {"BEGIN", Node_illegal, LEX_BEGIN, 0},
  1388.    {"END", Node_illegal, LEX_END, 0},
  1389.    {"atan2", Node_builtin, LEX_BUILTIN, do_atan2},
  1390. #ifndef FAST
  1391.    {"bp", Node_builtin, LEX_BUILTIN, do_bp},
  1392. #endif
  1393.    {"break", Node_K_break, LEX_BREAK, 0},
  1394.    {"close", Node_builtin, LEX_BUILTIN, do_close},
  1395.    {"continue", Node_K_continue, LEX_CONTINUE, 0},
  1396.    {"cos", Node_builtin, LEX_BUILTIN, do_cos},
  1397.    {"else", Node_illegal, LEX_ELSE, 0},
  1398.    {"exit", Node_K_exit, LEX_EXIT, 0},
  1399.    {"exp", Node_builtin, LEX_BUILTIN, do_exp},
  1400.    {"for", Node_K_for, LEX_FOR, 0},
  1401.    {"getline", Node_K_getline, LEX_GETLINE, do_getline},
  1402.    {"gsub", Node_builtin, LEX_SUB, do_gsub},
  1403.    {"if", Node_K_if, LEX_IF, 0},
  1404.    {"in", Node_illegal, LEX_IN, 0},
  1405.    {"index", Node_builtin, LEX_BUILTIN, do_index},
  1406.    {"int", Node_builtin, LEX_BUILTIN, do_int},
  1407.    {"length", Node_builtin, LEX_BUILTIN, do_length},
  1408.    {"log", Node_builtin, LEX_BUILTIN, do_log},
  1409.    {"match", Node_builtin, LEX_BUILTIN, do_match},
  1410.    {"next", Node_K_next, LEX_NEXT, 0},
  1411.    {"print", Node_K_print, LEX_PRINT, 0},
  1412.    {"printf", Node_K_printf, LEX_PRINTF, 0},
  1413. #ifndef FAST
  1414.    {"prvars", Node_builtin, LEX_BUILTIN, do_prvars},
  1415. #endif
  1416.    {"rand", Node_builtin, LEX_BUILTIN, do_rand},
  1417.    {"sin", Node_builtin, LEX_BUILTIN, do_sin},
  1418.    {"split", Node_builtin, LEX_BUILTIN, do_split},
  1419.    {"sprintf", Node_builtin, LEX_BUILTIN, do_sprintf},
  1420.    {"srand", Node_builtin, LEX_BUILTIN, do_srand},
  1421.    {"sqrt", Node_builtin, LEX_BUILTIN, do_sqrt},
  1422.    {"sub", Node_builtin, LEX_SUB, do_sub},
  1423.    {"substr", Node_builtin, LEX_BUILTIN, do_substr},
  1424.    {"system", Node_builtin, LEX_BUILTIN, do_system},
  1425.    {"while", Node_K_while, LEX_WHILE, 0},
  1426.    {NULL, Node_illegal, ERROR, 0}
  1427. };
  1428.  
  1429. /* Read one token, getting characters through lexptr.  */
  1430.  
  1431. static int yylex()
  1432. {
  1433.    register int c;
  1434.    register int namelen;
  1435.    register char *tokstart;
  1436.    register struct token *toktab, *low, *high, *mid;
  1437.    int dif;
  1438.    double atof();                      /* JF know what happens if you forget this? */
  1439.  
  1440.    static did_newline = 0;             /* JF the grammar insists that actions end with newlines. This was easier than hacking the
  1441.                                         * grammar. */
  1442.    int do_concat;
  1443.  
  1444.    int seen_e = 0;                     /* These are for numbers */
  1445.    int seen_point = 0;
  1446.  
  1447. retry:
  1448.  
  1449.    if (!lexptr)
  1450.       return 0;
  1451.  
  1452.    if (want_regexp)
  1453.    {
  1454.       want_regexp = 0;
  1455.       /**
  1456.        * there is a potential bug if a regexp is followed by an equal sign:
  1457.        * "/foo/=bar" would result in assign_quotient being returned as the
  1458.        * next token.  Nothing is done about it since it is not valid awk,
  1459.        * but maybe something should be done anyway.
  1460.        */
  1461.  
  1462.       tokstart = lexptr;
  1463.       while (c = *lexptr++)
  1464.       {
  1465.          switch (c)
  1466.          {
  1467.          case '\\':
  1468.             if (*lexptr++ == '\0')
  1469.             {
  1470.                yyerror("unterminated regexp ends with \\");
  1471.                return ERROR;
  1472.             }
  1473.             break;
  1474.          case '/':                    /* end of the regexp */
  1475.             lexptr--;
  1476.             yylval.sval = tokstart;
  1477.             return REGEXP;
  1478.          case '\n':
  1479.          case '\0':
  1480.             yyerror("unterminated regexp");
  1481.             return ERROR;
  1482.          }
  1483.       }
  1484.    }
  1485.    do_concat = want_concat_token;
  1486.    want_concat_token = 0;
  1487.  
  1488.    if (*lexptr == '\0')
  1489.    {
  1490.       lexptr = 0;
  1491.       return NEWLINE;
  1492.    }
  1493.  
  1494.    /*
  1495.     * if lexptr is at white space between two terminal tokens or parens,
  1496.     * it is a concatenation operator. 
  1497.     */
  1498.    if (do_concat && (*lexptr == ' ' || *lexptr == '\t'))
  1499.    {
  1500.       while (*lexptr == ' ' || *lexptr == '\t')
  1501.          lexptr++;
  1502.       if (isalnum(*lexptr) || *lexptr == '\"' || *lexptr == '(' || *lexptr == '.' || *lexptr == '$')
  1503.          /* the '.' is for decimal pt */
  1504.          return CONCAT_OP;
  1505.    }
  1506.  
  1507.    while (*lexptr == ' ' || *lexptr == '\t')
  1508.       lexptr++;
  1509.  
  1510.    tokstart = lexptr;                  /* JF */
  1511.  
  1512.    switch (c = *lexptr++)
  1513.    {
  1514.    case 0:
  1515.       return 0;
  1516.  
  1517.    case '\n':
  1518.       lineno++;
  1519.       return NEWLINE;
  1520.  
  1521.    case '#':                          /* it's a comment */
  1522.       while (*lexptr != '\n' && *lexptr != '\0')
  1523.          lexptr++;
  1524.       goto retry;
  1525.  
  1526.    case '\\':
  1527.       if (*lexptr == '\n')
  1528.       {
  1529.          lexptr++;
  1530.          goto retry;
  1531.       }
  1532.       else
  1533.          break;
  1534.    case ')':
  1535.    case ']':
  1536.       ++want_concat_token;
  1537.       /* fall through */
  1538.    case '(':                          /* JF these were above, but I don't see why they should turn on concat. . . & */
  1539.    case '[':
  1540.  
  1541.    case '{':
  1542.    case ',':                          /* JF */
  1543.    case '$':
  1544.    case ';':
  1545.    case ':':
  1546.    case '?':
  1547.       /*
  1548.        * set node type to ILLEGAL because the action should set it to the right thing 
  1549.        */
  1550.       yylval.nodetypeval = Node_illegal;
  1551.       return c;
  1552.  
  1553.    case '^':
  1554.       if (*lexptr == '=')
  1555.       {
  1556.          yylval.nodetypeval = Node_assign_pow;
  1557.          lexptr++;
  1558.          return ASSIGNOP;
  1559.       }
  1560.       yylval.nodetypeval = Node_illegal;
  1561.       return c;
  1562.  
  1563.    case '*':
  1564.       if (*lexptr == '=')
  1565.       {
  1566.          yylval.nodetypeval = Node_assign_times;
  1567.          lexptr++;
  1568.          return ASSIGNOP;
  1569.       }
  1570.       yylval.nodetypeval = Node_illegal;
  1571.       return c;
  1572.  
  1573.    case '/':
  1574.       if (*lexptr == '=')
  1575.       {
  1576.          yylval.nodetypeval = Node_assign_quotient;
  1577.          lexptr++;
  1578.          return ASSIGNOP;
  1579.       }
  1580.       yylval.nodetypeval = Node_illegal;
  1581.       return c;
  1582.  
  1583.    case '%':
  1584.       if (*lexptr == '=')
  1585.       {
  1586.          yylval.nodetypeval = Node_assign_mod;
  1587.          lexptr++;
  1588.          return ASSIGNOP;
  1589.       }
  1590.       yylval.nodetypeval = Node_illegal;
  1591.       return c;
  1592.  
  1593.    case '+':
  1594.       if (*lexptr == '=')
  1595.       {
  1596.          yylval.nodetypeval = Node_assign_plus;
  1597.          lexptr++;
  1598.          return ASSIGNOP;
  1599.       }
  1600.       if (*lexptr == '+')
  1601.       {
  1602.          yylval.nodetypeval = Node_illegal;
  1603.          lexptr++;
  1604.          return INCREMENT;
  1605.       }
  1606.       yylval.nodetypeval = Node_illegal;
  1607.       return c;
  1608.  
  1609.    case '!':
  1610.       if (*lexptr == '=')
  1611.       {
  1612.          yylval.nodetypeval = Node_notequal;
  1613.          lexptr++;
  1614.          return RELOP;
  1615.       }
  1616.       if (*lexptr == '~')
  1617.       {
  1618.          yylval.nodetypeval = Node_nomatch;
  1619.          lexptr++;
  1620.          return MATCHOP;
  1621.       }
  1622.       yylval.nodetypeval = Node_illegal;
  1623.       return c;
  1624.  
  1625.    case '<':
  1626.       if (want_redirect)
  1627.       {
  1628.          yylval.nodetypeval = Node_redirect_input;
  1629.          return REDIRECT_OP;
  1630.       }
  1631.       if (*lexptr == '=')
  1632.       {
  1633.          yylval.nodetypeval = Node_leq;
  1634.          lexptr++;
  1635.          return RELOP;
  1636.       }
  1637.       yylval.nodetypeval = Node_less;
  1638.       return RELOP;
  1639.  
  1640.    case '=':
  1641.       if (*lexptr == '=')
  1642.       {
  1643.          yylval.nodetypeval = Node_equal;
  1644.          lexptr++;
  1645.          return RELOP;
  1646.       }
  1647.       yylval.nodetypeval = Node_assign;
  1648.       return ASSIGNOP;
  1649.  
  1650.    case '>':
  1651.       if (want_redirect)
  1652.       {
  1653.          if (*lexptr == '>')
  1654.          {
  1655.             yylval.nodetypeval = Node_redirect_append;
  1656.             lexptr++;
  1657.          }
  1658.          else
  1659.             yylval.nodetypeval = Node_redirect_output;
  1660.          return REDIRECT_OP;
  1661.       }
  1662.       if (*lexptr == '=')
  1663.       {
  1664.          yylval.nodetypeval = Node_geq;
  1665.          lexptr++;
  1666.          return RELOP;
  1667.       }
  1668.       yylval.nodetypeval = Node_greater;
  1669.       return RELOP;
  1670.  
  1671.    case '~':
  1672.       yylval.nodetypeval = Node_match;
  1673.       return MATCHOP;
  1674.  
  1675.    case '}':
  1676.       if (did_newline)
  1677.       {
  1678.          did_newline = 0;
  1679.          return c;
  1680.       }
  1681.       did_newline++;
  1682.       --lexptr;
  1683.       return NEWLINE;
  1684.  
  1685.    case '"':
  1686.       while (*lexptr != '\0')
  1687.       {
  1688.          switch (*lexptr++)
  1689.          {
  1690.          case '\\':
  1691.             if (*lexptr++ != '\0')
  1692.                break;
  1693.             /* fall through */
  1694.          case '\n':
  1695.             yyerror("unterminated string");
  1696.             return ERROR;
  1697.          case '\"':
  1698.             yylval.sval = tokstart + 1;/* JF Skip the doublequote */
  1699.             ++want_concat_token;
  1700.             return YSTRING;
  1701.          }
  1702.       }
  1703.       return ERROR;                    /* JF this was one level up, wrong? */
  1704.  
  1705.    case '-':
  1706.       if (*lexptr == '=')
  1707.       {
  1708.          yylval.nodetypeval = Node_assign_minus;
  1709.          lexptr++;
  1710.          return ASSIGNOP;
  1711.       }
  1712.       if (*lexptr == '-')
  1713.       {
  1714.          yylval.nodetypeval = Node_illegal;
  1715.          lexptr++;
  1716.          return DECREMENT;
  1717.       }
  1718.       /*
  1719.        * JF I think space tab comma and newline are the legal places for a UMINUS.  Have I missed any? 
  1720.        */
  1721.       if ((!isdigit(*lexptr) && *lexptr != '.') || (lexptr > lexptr_begin + 1 && !index(" \t,\n", lexptr[-2])))
  1722.       {
  1723.          /*
  1724.           * set node type to ILLEGAL because the action should set it to the right thing 
  1725.           */
  1726.          yylval.nodetypeval = Node_illegal;
  1727.          return c;
  1728.       }
  1729.       /* FALL through into number code */
  1730.    case '0':
  1731.    case '1':
  1732.    case '2':
  1733.    case '3':
  1734.    case '4':
  1735.    case '5':
  1736.    case '6':
  1737.    case '7':
  1738.    case '8':
  1739.    case '9':
  1740.    case '.':
  1741.       /* It's a number */
  1742.       if (c == '-')
  1743.          namelen = 1;
  1744.       else
  1745.          namelen = 0;
  1746.       for (; (c = tokstart[namelen]) != '\0'; namelen++)
  1747.       {
  1748.          switch (c)
  1749.          {
  1750.          case '.':
  1751.             if (seen_point)
  1752.                goto got_number;
  1753.             ++seen_point;
  1754.             break;
  1755.          case 'e':
  1756.          case 'E':
  1757.             if (seen_e)
  1758.                goto got_number;
  1759.             ++seen_e;
  1760.             if (tokstart[namelen + 1] == '-' || tokstart[namelen + 1] == '+')
  1761.                namelen++;
  1762.             break;
  1763.          case '0':
  1764.          case '1':
  1765.          case '2':
  1766.          case '3':
  1767.          case '4':
  1768.          case '5':
  1769.          case '6':
  1770.          case '7':
  1771.          case '8':
  1772.          case '9':
  1773.             break;
  1774.          default:
  1775.             goto got_number;
  1776.          }
  1777.       }
  1778.  
  1779.       /*
  1780.        * There seems to be a bug (feature?) in the Microsoft Large Model
  1781.        * atof function.  If the string to convert is too long, atof returns a
  1782.        * zero without bothering to scan the string.  The following hack simply
  1783.        * truncates tokstart for the duration of the call. -ADE- 
  1784.        */
  1785.  
  1786. got_number:
  1787.       lexptr = tokstart + namelen;
  1788.       *lexptr = '\0';
  1789.       yylval.fval = atof(tokstart);
  1790.       *lexptr = c;
  1791.       ++want_concat_token;
  1792.       return NUMBER;
  1793.  
  1794.    case '&':
  1795.       if (*lexptr == '&')
  1796.       {
  1797.          yylval.nodetypeval = Node_and;
  1798.          lexptr++;
  1799.          return LEX_AND;
  1800.       }
  1801.       return ERROR;
  1802.  
  1803.    case '|':
  1804.       if (want_redirect)
  1805.       {
  1806.          lexptr++;
  1807.          yylval.nodetypeval = Node_redirect_pipe;
  1808.          return REDIRECT_OP;
  1809.       }
  1810.       if (*lexptr == '|')
  1811.       {
  1812.          yylval.nodetypeval = Node_or;
  1813.          lexptr++;
  1814.          return LEX_OR;
  1815.       }
  1816.       return ERROR;
  1817.    }
  1818.  
  1819.    if (!(is_identchar(c)))
  1820.    {
  1821.       yyerror("Invalid char '%c' in expression\n", c);
  1822.       return ERROR;
  1823.    }
  1824.  
  1825.    /* its some type of name-type-thing.  Find its length */
  1826.    for (namelen = 0; is_identchar(tokstart[namelen]); namelen++)
  1827.       ;
  1828.  
  1829.  
  1830.    /* See if it is a special token.      */
  1831.  
  1832.    low = tokentab;
  1833.    high = END(tokentab);
  1834.    while (low <= high)
  1835.    {
  1836.       mid = low + (high - low) / 2;
  1837.       if (!(dif = strncmp(tokstart, mid->operator, namelen)) &&
  1838.           *tokstart == mid->operator[0] && mid->operator[namelen] == '\0')
  1839.       {
  1840.          lexptr = tokstart + namelen;
  1841.          if (mid->class == LEX_BUILTIN || mid->class == LEX_SUB)
  1842.             yylval.ptrval = mid->ptr;
  1843.          else
  1844.             yylval.nodetypeval = mid->value;
  1845.          return mid->class;
  1846.       }
  1847.       else if (dif > 0)
  1848.          low = mid + 1;
  1849.       else
  1850.          high = mid - 1;
  1851.    }
  1852.  
  1853.    /*
  1854.     * for (toktab = tokentab; toktab->operator != NULL; toktab++)
  1855.     * {
  1856.     *    if(*tokstart == toktab->operator[0] && !strncmp(tokstart, toktab->operator, namelen)
  1857.     *           && toktab->operator[namelen]=='\0')
  1858.     *    {
  1859.     *       lexptr = tokstart + namelen;
  1860.     *       if(toktab->class == LEX_BUILTIN || toktab->class == LEX_SUB)
  1861.     *          yylval.ptrval = toktab->ptr;
  1862.     *       else
  1863.     *          lexptr = tokstart + namelen;
  1864.     *       if(toktab->class == LEX_BUILTIN || toktab->class == LEX_SUB)
  1865.     *          yylval.ptrval = toktab->ptr;
  1866.     *       else
  1867.     *          yylval.nodetypeval = toktab->value;
  1868.     *       return toktab->class;
  1869.     *    }
  1870.     * }
  1871.     */
  1872.    yylval.sval = tokstart;
  1873.    lexptr = tokstart + namelen;
  1874.    ++want_concat_token;
  1875.    return NAME;
  1876. }
  1877.  
  1878. void yyerror(mesg, a1, a2, a3, a4, a5, a6, a7, a8)
  1879. char *mesg;
  1880. {
  1881.    register char *ptr, *beg;
  1882.  
  1883.    /* Find the current line in the input file */
  1884.    if (!lexptr)
  1885.    {
  1886.       beg = "(END OF FILE)";
  1887.       ptr = beg + 13;
  1888.    }
  1889.    else
  1890.    {
  1891.       if (*lexptr == '\n' && lexptr != lexptr_begin)
  1892.          --lexptr;
  1893.       for (beg = lexptr; beg != lexptr_begin && *beg != '\n'; --beg)
  1894.          ;
  1895.       for (ptr = lexptr; *ptr && *ptr != '\n'; ptr++)   /* jfw: NL isn't guaranteed */
  1896.          ;
  1897.       if (beg != lexptr_begin)
  1898.          beg++;
  1899.    }
  1900.    fprintf(stderr, "Error near line %d,  '%.*s'\n", lineno, ptr - beg, beg);
  1901.    /* figure out line number, etc. later */
  1902.    fprintf(stderr, mesg, a1, a2, a3, a4, a5, a6, a7, a8);
  1903.    fprintf(stderr, "\n");
  1904.    exit(1);
  1905. }
  1906.  
  1907. /*
  1908.  * Parse a C escape sequence.
  1909.  * STRING_PTR points to a variable containing a pointer to the string to
  1910.  * parse.  That pointer is updated past the characters we use.  The value of
  1911.  * the escape sequence is returned. 
  1912.  *
  1913.  * A negative value means the sequence \ newline was seen, which is supposed
  1914.  * to be equivalent to nothing at all. 
  1915.  *
  1916.  * If \ is followed by a null character, we return a negative value and leave
  1917.  * the string pointer pointing at the null character. 
  1918.  *
  1919.  * If \ is followed by 000, we return 0 and leave the string pointer after
  1920.  * the zeros.  A value of 0 does not mean end of string.  
  1921.  */
  1922.  
  1923. static int parse_escape(string_ptr)
  1924. char **string_ptr;
  1925. {
  1926.    register int c = *(*string_ptr)++;
  1927.  
  1928.    switch (c)
  1929.    {
  1930.    case 'a':
  1931.       return '\a';
  1932.    case 'b':
  1933.       return '\b';
  1934.    case 'e':
  1935.       return 033;
  1936.    case 'f':
  1937.       return '\f';
  1938.    case 'n':
  1939.       return '\n';
  1940.    case 'r':
  1941.       return '\r';
  1942.    case 't':
  1943.       return '\t';
  1944.    case 'v':
  1945.       return '\v';
  1946.    case '\n':
  1947.       return -2;
  1948.    case 0:
  1949.       (*string_ptr)--;
  1950.       return 0;
  1951.    case '^':
  1952.       c = *(*string_ptr)++;
  1953.       if (c == '\\')
  1954.          c = parse_escape(string_ptr);
  1955.       if (c == '?')
  1956.          return 0177;
  1957.       return (c & 0200) | (c & 037);
  1958.  
  1959.    case '0':
  1960.    case '1':
  1961.    case '2':
  1962.    case '3':
  1963.    case '4':
  1964.    case '5':
  1965.    case '6':
  1966.    case '7':
  1967.       {
  1968.          register int i = c - '0';
  1969.          register int count = 0;
  1970.          while (++count < 3)
  1971.          {
  1972.             if ((c = *(*string_ptr)++) >= '0' && c <= '7')
  1973.             {
  1974.                i *= 8;
  1975.                i += c - '0';
  1976.             }
  1977.             else
  1978.             {
  1979.                (*string_ptr)--;
  1980.                break;
  1981.             }
  1982.          }
  1983.          return i;
  1984.       }
  1985.    default:
  1986.       return c;
  1987.    }
  1988. }
  1989.