parser.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "region.h"
  5. #include "stringport.h"
  6. #include "tokenizer.h"
  7. #include "parser.h"
  8. #include "reporting.h"
  9. char *operator_for[] = {
  10. [NODE_PIPE] = "|",
  11. [NODE_CONJ] = "&&",
  12. [NODE_DISJ] = "||",
  13. };
  14. struct AST* parse_binop(region *r, char **tokens, NodeType ty)
  15. {
  16. char **stokens;
  17. struct AST* n;
  18. struct AST* m;
  19. stokens = tokens;
  20. if (ty == NODE_COMMAND) {
  21. if (!tokens[0]) {
  22. report("Error: bad syntax, zero-length command\n");
  23. return NULL;
  24. }
  25. n = region_malloc(r, sizeof(struct AST));
  26. n->type = NODE_COMMAND;
  27. n->node.tokens = stokens;
  28. return n;
  29. }
  30. while (tokens[0]) {
  31. if (!strcmp(operator_for[ty], tokens[0])) {
  32. tokens[0] = NULL;
  33. m = region_malloc(r, sizeof(struct AST));
  34. m->type = ty;
  35. if (!(m->node.child.l = parse_binop(r, stokens, ty-1)))
  36. return NULL;
  37. if (!(m->node.child.r = parse_binop(r, tokens+1, ty)))
  38. return NULL;
  39. return m;
  40. }
  41. else {
  42. tokens++;
  43. }
  44. }
  45. return parse_binop(r, stokens, ty-1);
  46. }
  47. struct AST* parse_tokens(region *r, char **tokens, int *bg_flag)
  48. {
  49. int i = 0;
  50. while (tokens[i])
  51. i++;
  52. if (i > 0 && !strcmp("&", tokens[i-1])) {
  53. *bg_flag=1;
  54. tokens[--i] = NULL;
  55. }
  56. else {
  57. *bg_flag=0;
  58. }
  59. return parse_binop(r, tokens, NODE_DISJ);
  60. }
  61. struct AST* parse(region *r, string_port *port, int *bg_flag)
  62. {
  63. char **tokens = read_tokens(r, port);
  64. if (!tokens)
  65. return NULL;
  66. if (tokens[0])
  67. return parse_tokens(r, tokens, bg_flag);
  68. return NULL;
  69. }