summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bu-parser.c24
-rw-r--r--bu-parser.h11
-rw-r--r--main.c6
-rw-r--r--tree.c7
-rw-r--r--tree.h1
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,
diff --git a/main.c b/main.c
index 5d51875..0477bae 100644
--- a/main.c
+++ b/main.c
@@ -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;
diff --git a/tree.c b/tree.c
index b53ece2..fbb561a 100644
--- a/tree.c
+++ b/tree.c
@@ -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);
+}
+
diff --git a/tree.h b/tree.h
index 8df9f53..c18ccae 100644
--- a/tree.h
+++ b/tree.h
@@ -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