Advertisement
Guest User

Shunting Yard

a guest
Apr 27th, 2024
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.02 KB | None | 0 0
  1. /************
  2.  * collapse *
  3.  ************/
  4.  
  5. /* shunting yard helper */
  6.  
  7. int
  8. collapse(struct vector *outq, struct vector *opq, struct exp **res)
  9. {
  10.     struct exp *left, *right;
  11.     struct binop *infix;
  12.     enum op_type op;
  13.  
  14.     op = (enum op_type)vec_pop(opq);
  15.     left = (struct exp *)vec_pop(outq);
  16.     right = (struct exp *)vec_pop(outq);
  17.     infix = binop_alloc(op, left, right);
  18.     *res = exp_alloc(E_BINOP, infix);
  19.     return 0;
  20. }
  21.  
  22. /*********
  23.  * shunt *
  24.  *********/
  25.  
  26. /* implementation of the shunting-yard infix parser algorithm */
  27.  
  28. int
  29. shunt(struct lexer *lex, struct token *tok, struct exp **res)
  30. {
  31.     struct vector *outq, *opq;
  32.     struct exp *acc;
  33.     struct bind_power cur_bp, prev_bp;
  34.     int status;
  35.  
  36.     outq = vec_alloc(2, (void (*)(void *))exp_free);
  37.     opq = vec_alloc(2, 0);
  38.  
  39.     while (1) {
  40.  
  41.         scan(lex, tok);
  42.  
  43.         /* the token is delimiting the end of an expression */
  44.  
  45.         if (exp_follow(tok->type))
  46.             break;
  47.        
  48.         /* the token is an operator */
  49.  
  50.         if (is_infix(tok->type)) {
  51.             cur_bp = bind_table[tok->type];
  52.             prev_bp = bind_table[vec_peek(opq)];
  53.  
  54.             while (!vec_empty(opq) && cur_bp.left <= prev_bp.left) {
  55.                 status = collapse(outq, opq, &acc);
  56.                 vec_push(outq, (uintptr_t)acc);
  57.             }
  58.  
  59.             vec_push(opq, (enum op_type)tok->type);
  60.             continue;
  61.         }
  62.  
  63.         /* the token is delimiting the beginning of an atomic expression */
  64.  
  65.         status = expr_at(lex, tok, &acc);
  66.  
  67.         if (status < 0)
  68.             goto shunt_cleanup;
  69.        
  70.         vec_push(outq, (uintptr_t)acc);
  71.  
  72.         // no other case
  73.     }
  74.  
  75.     /* pick up rest of outq */
  76.  
  77.     while (!vec_empty(opq)) {
  78.         status = collapse(outq, opq, &acc);
  79.         vec_push(outq, (uintptr_t)acc);
  80.     }
  81.  
  82.     /* ASSERT OUTQ HAS LEN 1 */
  83.  
  84.     acc = (struct exp *)vec_pop(outq);
  85.     *res = acc;
  86.  
  87. shunt_cleanup:
  88.  
  89.     vec_free(outq);
  90.     vec_free(opq);
  91.    
  92.     return 0;
  93. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement