home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d0xx / d092 / bawk.lha / Bawk / bawkparse.c < prev    next >
Encoding:
Text File  |  1987-08-22  |  7.1 KB  |  369 lines

  1. X/*
  2. X * Bawk C actions parser
  3. X */
  4. X#include <stdio.h>
  5. X#include "bawk.h"
  6. X
  7. Xstatic char operator_strength[] = {
  8. X0,  /* 0 */
  9. X0,  /* CHAR */
  10. X0,  /* BOL */
  11. X0,  /* EOL */
  12. X0,  /* ANY */
  13. X0,  /* CLASS */
  14. X0,  /* NCLASS */
  15. X0,  /* STAR */
  16. X0,  /* PLUS */
  17. X0,  /* MINUS */
  18. X0,  /* ALPHA */
  19. X0,  /* DIGIT */
  20. X0,  /* NALPHA */
  21. X0,  /* PUNCT */
  22. X0,  /* RANGE */
  23. X0,  /* ENDPAT */
  24. X0,  /* T_STRING */
  25. X0,  /* T_DOLLAR */
  26. X0,  /* T_REGEXP */
  27. X0,  /* T_REGEXP_ARG */
  28. X0,  /* T_CONSTANT */
  29. X0,  /* T_VARIABLE */
  30. X0,  /* T_FUNCTION */
  31. X0,  /* T_SEMICOLON */
  32. X0,  /* T_EOF */
  33. X0,  /* T_LBRACE */
  34. X0,  /* T_RBRACE */
  35. X0,  /* T_LPAREN */
  36. X0,  /* T_RPAREN */
  37. X0,  /* T_LBRACKET */
  38. X0,  /* T_RBRACKET */
  39. X0,  /* T_COMMA */
  40. X1,  /* T_ASSIGN */
  41. X0,  /* T_STAR */
  42. X11, /* T_MUL */
  43. X11, /* T_DIV */
  44. X11, /* T_MOD */
  45. X10, /* T_ADD */
  46. X0,  /* T_UMINUS */
  47. X10, /* T_SUB */
  48. X9,  /* T_SHL */
  49. X9,  /* T_SHR */
  50. X8,  /* T_LT */
  51. X8,  /* T_LE */
  52. X8,  /* T_GT */
  53. X8,  /* T_GE */
  54. X7,  /* T_EQ */
  55. X7,  /* T_NE */
  56. X0,  /* T_NOT */
  57. X0,  /* T_ADDROF */
  58. X6,  /* T_AND */
  59. X5,  /* T_XOR */
  60. X4,  /* T_OR */
  61. X0,  /* T_LNOT */
  62. X3,  /* T_LAND */
  63. X2,  /* T_LOR */
  64. X0,  /* T_INCR */
  65. X0,  /* T_DECR */
  66. X0,  /* T_POSTINCR */
  67. X0,  /* T_POSTDECR */
  68. X0,  /* T_IF */
  69. X0,  /* T_ELSE */
  70. X0,  /* T_WHILE */
  71. X0,  /* T_BREAK */
  72. X0,  /* T_CHAR */
  73. X0,  /* T_INT */
  74. X0,  /* T_BEGIN */
  75. X0,  /* T_END */
  76. X0,  /* T_NF */
  77. X0,  /* T_NR */
  78. X0,  /* T_FS */
  79. X0,  /* T_RS */
  80. X0,  /* T_FILENAME */
  81. X0,  /* T_STATEMENT */
  82. X0,  /* T_DECLARE */
  83. X0   /* T_ARRAY_DECLARE */
  84. X};
  85. X
  86. XEXPR_NODE *stmt_parse()
  87. X{
  88. X    /*
  89. X     * Parse a statement.
  90. X     */
  91. X    register EXPR_NODE *root = NULL, *end_pointer, *tmp;
  92. X
  93. X    DBUG_ENTER("stmt_parse");
  94. X    switch ( Token )
  95. X    {
  96. X    case T_EOF:
  97. X        break;
  98. X    case T_CHAR:
  99. X    case T_INT:
  100. X        root = declist_parse();
  101. X        break;
  102. X    case T_LBRACE:
  103. X        /*
  104. X         * parse a compound statement
  105. X         */
  106. X        getoken();
  107. X        while ( Token != T_RBRACE )
  108. X        {
  109. X            tmp = get_expr_node((char) T_STATEMENT);
  110. X            if(!root) {
  111. X                root = end_pointer = tmp;
  112. X            } else {
  113. X                end_pointer->right = tmp;
  114. X                end_pointer = tmp;
  115. X            }
  116. X            end_pointer->left = stmt_parse();
  117. X        }
  118. X        if ( Token==T_RBRACE )
  119. X            getoken();
  120. X        break;
  121. X    case T_IF:
  122. X        /*
  123. X         * parse an "if-else" statement
  124. X         */
  125. X        if ( getoken() != T_LPAREN )
  126. X            syntaxerror();
  127. X        getoken();
  128. X        root = get_expr_node((char) T_IF);
  129. X        root->left = end_pointer = get_expr_node((char) T_IF);
  130. X        end_pointer->left = expr_parse();
  131. X        if ( Token!=T_RPAREN )
  132. X            syntaxerror();
  133. X        getoken();
  134. X        end_pointer->right = stmt_parse();
  135. X        if ( Token==T_ELSE )
  136. X        {
  137. X            getoken();
  138. X            root->right = stmt_parse();
  139. X        }
  140. X        break;
  141. X    case T_WHILE:
  142. X        /*
  143. X         * parse a "while" statement
  144. X         */
  145. X        root = get_expr_node((char) T_WHILE);
  146. X        if ( getoken() != T_LPAREN )
  147. X            syntaxerror();
  148. X
  149. X        getoken();
  150. X        root->left = expr_parse();
  151. X        if ( Token!=T_RPAREN )
  152. X            syntaxerror();
  153. X
  154. X        getoken();
  155. X        root->right = stmt_parse();
  156. X        break;
  157. X    case T_BREAK:
  158. X        /*
  159. X         * parse a "break" statement
  160. X         */
  161. X        root = get_expr_node((char) T_BREAK);
  162. X        getoken();
  163. X        break;
  164. X    case T_SEMICOLON:
  165. X        break;
  166. X    default:
  167. X        root = expr_parse();
  168. X    }
  169. X
  170. X    if ( Token==T_SEMICOLON )
  171. X        getoken();
  172. X    DBUG_RETURN(root);
  173. X}    
  174. X
  175. XEXPR_NODE *expr_parse()
  176. X{
  177. X    register EXPR_NODE *root, *tmp;
  178. X    register char strength;
  179. X
  180. X    DBUG_ENTER("expr_parse");
  181. X    strength = operator_strength[T_ASSIGN];
  182. X    root = expr_left_to_right_parse(strength);
  183. X    if(strength == operator_strength[Token])
  184. X    {
  185. X        /* assignments are grouped right to left */
  186. X        tmp = get_expr_node(Token);
  187. X        tmp->left = root;
  188. X        root = tmp;
  189. X        getoken();
  190. X        root->right = expr_parse();
  191. X    }
  192. X    DBUG_RETURN(root);
  193. X}
  194. X
  195. XEXPR_NODE *expr_left_to_right_parse(parent_strength)
  196. Xregister char parent_strength;
  197. X{
  198. X    register EXPR_NODE *root, *tmp;
  199. X    register char strength; 
  200. X
  201. X    DBUG_ENTER("expr_left_to_right_parse");
  202. X    root = primary_parse();
  203. X    if(parent_strength < (strength = operator_strength[Token]))
  204. X    {
  205. X        while(strength == operator_strength[Token])
  206. X        {
  207. X            tmp = get_expr_node(Token);
  208. X            tmp->left = root;
  209. X            root = tmp;
  210. X            getoken();
  211. X            root->right = expr_left_to_right_parse(strength);
  212. X        }
  213. X    }
  214. X    DBUG_RETURN(root);
  215. X}
  216. X
  217. XEXPR_NODE *primary_parse()
  218. X{
  219. X    register EXPR_NODE *root = NULL, *end_pointer, *tmp;
  220. X    register int lpar;
  221. X
  222. X    DBUG_ENTER("primary_parse");
  223. X    switch ( Token )
  224. X    {
  225. X    case T_LPAREN:
  226. X        /*
  227. X         * it's a parenthesized expression
  228. X         */
  229. X        getoken();
  230. X        root = expr_parse();
  231. X        if ( Token!=T_RPAREN )
  232. X            error( "missing ')'", ACT_ERROR );
  233. X        getoken();
  234. X        break;
  235. X    case T_LNOT:
  236. X    case T_NOT:
  237. X    case T_INCR:
  238. X    case T_DECR:
  239. X    case T_DOLLAR:
  240. X        root = get_expr_node(Token);
  241. X        getoken();
  242. X        root->left = primary_parse();
  243. X        break;
  244. X    case T_SUB:
  245. X        root = get_expr_node((char) T_UMINUS);
  246. X        getoken();
  247. X        root->left = primary_parse();
  248. X        break;
  249. X    case T_MUL:
  250. X        root = get_expr_node((char) T_STAR);
  251. X        getoken();
  252. X        root->left = primary_parse();
  253. X        break;
  254. X    case T_AND:
  255. X        root = get_expr_node((char) T_ADDROF);
  256. X        getoken();
  257. X        root->left = primary_parse();
  258. X        break;
  259. X    case T_ADD:
  260. X        getoken();
  261. X        root = primary_parse();
  262. X        break;
  263. X    case T_CONSTANT:
  264. X        root = get_expr_node(Token);
  265. X        root->left = (EXPR_NODE *) getmemory(sizeof(DATUM));
  266. X        ((DATUM *) (root->left))->ival = Value.ival;
  267. X        getoken();
  268. X        break;
  269. X    case T_FUNCTION:
  270. X        root = get_expr_node(Token);
  271. X        root->left = (EXPR_NODE *) getmemory(sizeof(DATUM));
  272. X        ((DATUM *) (root->left))->ival = Value.ival;
  273. X        getoken();
  274. X        if ( Token==T_LPAREN )
  275. X        {
  276. X            lpar = 1;
  277. X            getoken();
  278. X        }
  279. X        else
  280. X            lpar = 0;
  281. X        /*
  282. X         * Parse arguments into a list of expressions.
  283. X         */
  284. X        if ( Token!=T_RPAREN && Token!=T_EOF )
  285. X        {
  286. X            for ( ;; )
  287. X            {
  288. X                tmp = get_expr_node((char) T_FUNCTION);
  289. X                if(!root->right) {
  290. X                    root->right = end_pointer = tmp;
  291. X                } else {
  292. X                    end_pointer->right = tmp;
  293. X                    end_pointer = tmp;
  294. X                }
  295. X                end_pointer->left = expr_parse();
  296. X                if((tmp = end_pointer->left) &&
  297. X                   (tmp->operator == T_REGEXP))
  298. X                    tmp->operator = T_REGEXP_ARG;
  299. X                if ( Token==T_COMMA )
  300. X                    getoken();
  301. X                else
  302. X                    break;
  303. X            }
  304. X        }
  305. X        if ( lpar )
  306. X            if( Token!=T_RPAREN )
  307. X                error( "missing ')'", ACT_ERROR );
  308. X            else
  309. X                getoken();
  310. X        break;
  311. X    case T_REGEXP:
  312. X    case T_STRING:
  313. X        root = get_expr_node(Token);
  314. X        root->left = (EXPR_NODE *) getmemory(strlen(Value.dptr) + 1);
  315. X        strcpy((char *) root->left, Value.dptr);
  316. X        getoken();
  317. X        break;
  318. X    case T_NF:
  319. X    case T_NR:
  320. X    case T_FS:
  321. X    case T_RS:
  322. X    case T_FILENAME:
  323. X    case T_BEGIN:
  324. X    case T_END:
  325. X        root = get_expr_node(Token);
  326. X        getoken();
  327. X        break;
  328. X    case T_VARIABLE:
  329. X        root = get_expr_node(Token);
  330. X        root->left = (EXPR_NODE *) Value.dptr;
  331. X        getoken();
  332. X        break;
  333. X    case T_EOF:
  334. X        break;
  335. X    default:
  336. X        syntaxerror();
  337. X    }
  338. X    /*
  339. X     * a "[" means it's an array reference
  340. X     */
  341. X    if ( Token==T_LBRACKET )
  342. X    {
  343. X        tmp = get_expr_node(Token);
  344. X        tmp->left = root;
  345. X        root = tmp;
  346. X        getoken();
  347. X        root->right = expr_parse();
  348. X        if ( Token!=T_RBRACKET )
  349. X            error( "missing ']'", ACT_ERROR );
  350. X        getoken();
  351. X    }
  352. X
  353. X    if ( Token==T_INCR || Token==T_DECR )
  354. X    {
  355. X        tmp = get_expr_node((char)
  356. X                ((Token==T_INCR) ? T_POSTINCR : T_POSTDECR));
  357. X        tmp->left = root;
  358. X        root = tmp;
  359. X    }
  360. X    DBUG_RETURN(root);
  361. X}
  362. X
  363. Xvoid syntaxerror()
  364. X{
  365. X    DBUG_ENTER("syntaxerror");
  366. X    error( "syntax error", ACT_ERROR );
  367. X    DBUG_VOID_RETURN;
  368. X}
  369.