summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--expr.h9
-rw-r--r--expr.l50
-rw-r--r--expr.y64
4 files changed, 105 insertions, 25 deletions
diff --git a/Makefile b/Makefile
index 5fda526..33e958f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,8 @@
-expr: expr.c
- $(CC) -g -o $@ expr.c -ll
+expr: expr.c y.tab.c y.tab.h
+ $(CC) -g -o $@ expr.c y.tab.c -ll -ly
expr.c: expr.l
lex -t expr.l > expr.c
-
+y.tab.c y.tab.h: expr.y
+ yacc -d expr.y
diff --git a/expr.h b/expr.h
index e69de29..4b4a874 100644
--- a/expr.h
+++ b/expr.h
@@ -0,0 +1,9 @@
+typedef struct {
+ int type;
+ union {
+ int i;
+ char *s;
+ } u;
+} expr_yystype;
+
+#define YYSTYPE expr_yystype
diff --git a/expr.l b/expr.l
index 7612ebf..d6aa239 100644
--- a/expr.l
+++ b/expr.l
@@ -1,34 +1,42 @@
%{
-#define _XOPEN_SOURCE 2
+#define _XOPEN_SOURCE 700
#include <locale.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
+
#include "expr.h"
+
+#include "y.tab.h"
+
+extern int yyparse(void);
+
%}
DIGIT [0-9]
%%
-"|" puts("or");
-"&" puts("and");
-"=" puts("equal");
-">" puts("greater");
-">=" puts("greater or equal");
-"<" puts("less");
-"<=" puts("less or equal");
-"!=" puts("not equal");
-"+" puts("plus");
-"-" puts("minus");
-"*" puts("times");
-"/" puts("divide");
-"%" puts("remainder");
-"(" puts("lparen");
-")" puts("rparen");
-{DIGIT}+ printf("number %s\n", yytext);
--{DIGIT}+ printf("negative %s\n", yytext);
-.+ printf("string '%s'\n", yytext);
+"|" return OR;
+"&" return AND;
+"=" return COMPARISON;
+">" return COMPARISON;
+">=" return COMPARISON;
+"<" return COMPARISON;
+"<=" return COMPARISON;
+"!=" return COMPARISON;
+"+" return '+';
+"-" return '-';;
+"*" return MULTIPLICATION;
+"/" return MULTIPLICATION;
+"%" return MULTIPLICATION;
+"(" return '(';
+")" return ')';
+":" return MATCH;
+{DIGIT}+ { yylval.u.i = atoi(yytext); return yylval.type = INTEGER; }
+-{DIGIT}+ { yylval.u.i = atoi(yytext); return yylval.type = INTEGER; }
+.+ { yylval.u.s = strdup(yytext); return yylval.type = STRING; }
+\n ;
%%
@@ -58,11 +66,9 @@ int main(int argc, char *argv[])
for (int i = optind; i < argc; i++) {
fprintf(mem, "%s\n", argv[i]);
}
- fprintf(mem, "\n");
rewind(mem);
yyin = mem;
-
- return yylex();
+ return yyparse();
}
diff --git a/expr.y b/expr.y
new file mode 100644
index 0000000..950a772
--- /dev/null
+++ b/expr.y
@@ -0,0 +1,64 @@
+%{
+#include <stdio.h>
+
+#include "expr.h"
+
+extern int yylex(void);
+extern int yyerror(const char *s);
+
+static void breakpoint(void) { }
+%}
+
+%token INTEGER
+%token STRING
+%token '(' ')'
+%left MATCH MULTIPLICATION
+%left '+' '-'
+%left COMPARISON AND OR
+
+%start expr
+
+%%
+
+expr : STRING {
+ printf("string\n");
+ }
+
+ | INTEGER {
+ printf("integer %d\n", $1.u.i);
+ }
+
+ | '(' expr ')' {
+ printf("a parenthesized expression\n");
+ }
+
+ | expr MATCH expr {
+ printf("match two\n");
+ }
+
+ | expr MULTIPLICATION expr {
+ printf("multiplicationish\n");
+ }
+
+ | expr '+' expr {
+ printf("plus\n");
+ $$.u.i = $1.u.i + $3.u.i;
+ printf("%d\n", $$.u.i);
+ }
+
+ | expr '-' expr {
+ printf("minus\n");
+ }
+
+ | expr COMPARISON expr {
+ printf("compare\n");
+ }
+
+ | expr AND expr {
+ printf("and\n");
+ }
+
+ | expr OR expr {
+ printf("or\n");
+ }
+ ;