diff options
-rw-r--r-- | bu-parser.c | 24 | ||||
-rw-r--r-- | bu-parser.h | 11 | ||||
-rw-r--r-- | main.c | 6 | ||||
-rw-r--r-- | tree.c | 7 | ||||
-rw-r--r-- | tree.h | 1 |
5 files changed, 34 insertions, 15 deletions
diff --git a/bu-parser.c b/bu-parser.c index b077938..df4c2c2 100644 --- a/bu-parser.c +++ b/bu-parser.c @@ -2,12 +2,6 @@ #include "tree.h" #include <stdio.h> -void free_node(node *n) { - if (n->lhs) free_node(n->lhs); - if (n->rhs) free_node(n->rhs); - free(n); -} - void fprint_stack(FILE *stream, struct expr_parser *ep) { for (size_t i = 0; i < ep->stack_idx; i++) { struct stackmember m = ep->stack[i]; @@ -132,6 +126,20 @@ void unary_expr(struct expr_parser *ep) { ep->stack[ep->stack_idx - 1] = newm; } +void parens_expr(struct expr_parser *ep) { + struct stackmember o, e, c; + o = stack_pos(ep, 2); + e = stack_pos(ep, 1); + c = stack_pos(ep, 0); + BAIL_REDUCE_IF( + o.id != TOKEN_OPEN_PAREN + || e.id != STACKMEMBER_EXPR + || c.id != TOKEN_CLOSE_PAREN, "mismatched parenthesis"); + + ep->stack_idx -= 2; + ep->stack[ep->stack_idx - 1] = e; +} + int expr_parser_run(struct expr_parser *ep) { // prime the look-ahead ep->lahead = ep->lex(ep->lex_data); @@ -167,6 +175,10 @@ int expr_parser_run(struct expr_parser *ep) { } } break; + case TOKEN_CLOSE_PAREN: + parens_expr(ep); + noshift = 1; + break; default: break; } } diff --git a/bu-parser.h b/bu-parser.h index 7dc7034..8910b5d 100644 --- a/bu-parser.h +++ b/bu-parser.h @@ -7,17 +7,10 @@ #include "tree.h" /* PRODUCTION RULES - - <expr> ::= <expr> <binary_op> <expr> | <unary_op> <expr> | <var> + <expr> ::= <expr> <binary_op> <expr> | <unary_op> <expr> | "(" <expr> ")" | <var> <binary_op> ::= "*" | "+" <unary_op> ::= "!" <var> ::= r#[a-z] - - */ - -/* POSSIBILITIES - a-z => var - */ enum parser_state { @@ -31,6 +24,8 @@ enum token_id { TOKEN_BINARY_OPERATOR, TOKEN_UNARY_OPERATOR, TOKEN_VARIABLE, + TOKEN_OPEN_PAREN, + TOKEN_CLOSE_PAREN, TOKEN_EOS, TOKEN_OOB, TOKEN_MAX, @@ -23,6 +23,8 @@ struct chartoken lex_str(void *v) { case '!': token.id = TOKEN_UNARY_OPERATOR; break; case '*': case '+': token.id = TOKEN_BINARY_OPERATOR; break; + case '(': token.id = TOKEN_OPEN_PAREN; break; + case ')': token.id = TOKEN_CLOSE_PAREN; break; default: break; } } @@ -36,7 +38,9 @@ int main(){ scanf("%[^\n]", str); char str2[100]; strncpy(str2, str, 100); - printTree(parse(str2),0); + node *exp = parse(str2); + printTree(exp,0); + free_node(exp); struct lex_str_data lxd; lxd.str = str; @@ -62,3 +62,10 @@ void fprintTree(FILE *stream, node *root, int level) { void printTree(node *root, int level) { fprintTree(stdout, root, level); } + +void free_node(node *n) { + if (n->lhs) free_node(n->lhs); + if (n->rhs) free_node(n->rhs); + free(n); +} + @@ -23,5 +23,6 @@ typedef struct node { node * parse(char *str); void fprintTree(FILE *stream, node *root, int level); void printTree(node *root, int level); +void free_node(node *n); #endif |