rd.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /* A (memory leaking!) recursive descent parser for Bryan Ford's trivial
  2. * grammar:
  3. Additive <- Multitive '+' Additive | Multitive
  4. Multitive <- Primary '*' Multitive | Primary
  5. Primary <- '(' Additive ')' | Decimal
  6. Decimal <- '0' | '1' | ... | '9'
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. struct parsed {
  11. int value; /* semantic value */
  12. char *remainder; /* unparsed string */
  13. };
  14. struct parsed *additive(struct parsed *);
  15. struct parsed *multitive(struct parsed *);
  16. struct parsed *primary(struct parsed *);
  17. struct parsed *decimal(struct parsed *);
  18. struct parsed *additive(struct parsed *t) {
  19. struct parsed *m;
  20. m = multitive(t);
  21. if (m)
  22. if (m->remainder[0] == '+') {
  23. struct parsed *a;
  24. ++m->remainder;
  25. a = additive(m);
  26. if (a) {
  27. a->value = m->value + a->value;
  28. return a;
  29. }
  30. }
  31. return multitive(t);
  32. }
  33. struct parsed *multitive(struct parsed *t) {
  34. struct parsed *p;
  35. p = primary(t);
  36. if (p) {
  37. if (p->remainder[0] == '*') {
  38. struct parsed *m;
  39. ++p->remainder;
  40. m = multitive(p);
  41. if (p) {
  42. m->value = p->value * m->value;
  43. return m;
  44. }
  45. }
  46. }
  47. return primary(t);
  48. }
  49. struct parsed *primary(struct parsed *t) {
  50. if (t->remainder[0] == '(') {
  51. struct parsed *a;
  52. ++t->remainder;
  53. a = additive(t);
  54. --t->remainder;
  55. if (a)
  56. if (a->remainder[0] == ')') {
  57. ++a->remainder;
  58. return a;
  59. }
  60. }
  61. return decimal(t);
  62. }
  63. struct parsed *decimal(struct parsed *t) {
  64. char *in = t->remainder;
  65. if (in[0] >= '0' && in[0] <= '9') {
  66. struct parsed *sp;
  67. sp = malloc(sizeof (struct parsed));
  68. sp->value = in[0] - '0';
  69. sp->remainder = in + 1;
  70. return sp;
  71. }
  72. return 0;
  73. }
  74. int main(int argc, char **argv) {
  75. struct parsed i, *r;
  76. printf("%s\n", argv[1]);
  77. i.remainder = argv[1];
  78. r = additive(&i);
  79. if (r) {
  80. printf("==> %d\n", r->value);
  81. if (*r->remainder != '\0')
  82. printf("input not completely consumed\n");
  83. } else {
  84. printf("parse error\n");
  85. }
  86. return 0;
  87. }