aboutsummaryrefslogtreecommitdiff
path: root/sem3/osc/mm11
diff options
context:
space:
mode:
Diffstat (limited to 'sem3/osc/mm11')
-rw-r--r--sem3/osc/mm11/opgaver.md32
-rw-r--r--sem3/osc/mm11/regn/Makefile30
-rw-r--r--sem3/osc/mm11/regn/regn.l40
-rw-r--r--sem3/osc/mm11/regn/regn.y54
-rw-r--r--sem3/osc/mm11/regn/symtab.c50
-rw-r--r--sem3/osc/mm11/regn/symtab.h20
-rw-r--r--sem3/osc/mm11/regn2/Makefile30
-rw-r--r--sem3/osc/mm11/regn2/regn.l27
-rw-r--r--sem3/osc/mm11/regn2/regn.y46
9 files changed, 329 insertions, 0 deletions
diff --git a/sem3/osc/mm11/opgaver.md b/sem3/osc/mm11/opgaver.md
new file mode 100644
index 0000000..276236a
--- /dev/null
+++ b/sem3/osc/mm11/opgaver.md
@@ -0,0 +1,32 @@
+# Opgave 1
+
+Mange af dem er okay.
+
+```
+<program> ::= 'program''(' <ident> ')' <statementlist> 'end'.
+<statementlist> ::= <statement> <statementlist> | e
+<statement> ::= <ident> '=' <exp>;
+
+<exp> ::= <term> <expB>
+<expB> ::= <termopr> <term> <expB> | e
+
+<term> ::= <factor> <termB>
+<termB> ::= <factoropr> <factor> <termB> | e
+<termopr> ::= '+' | '-'
+
+<factor> ::= '(' <exp> ')' | <ident>
+<factoropr> ::= '*' | '/'
+```
+
+# Opgave 2
+
+Denne laver jeg måske senere.
+
+# Opgave 3
+
+Denne er løst i regn mappen.
+Kør `make run` deri for at køre.
+
+# Opgave 4
+
+I regn2 mappen
diff --git a/sem3/osc/mm11/regn/Makefile b/sem3/osc/mm11/regn/Makefile
new file mode 100644
index 0000000..442feba
--- /dev/null
+++ b/sem3/osc/mm11/regn/Makefile
@@ -0,0 +1,30 @@
+
+LEX=flex
+YACC=bison
+LIBS=-ly -lfl -lm
+CC=gcc
+
+PROG=regn
+TRASH=lex.yy.c $(PROG).tab.c $(PROG) $(PROG).tab.h $(PROG).output
+
+$(PROG): $(PROG).tab.o lex.yy.o symtab.o
+ $(CC) -o $@ $^ $(LIBS)
+
+$(PROG).tab.c $(PROG).tab.h: $(PROG).y
+ $(YACC) -d -v $(PROG).y
+
+lex.yy.c: $(PROG).l
+ $(LEX) $(PROG).l
+
+%.o: %.c
+ $(CC) -c -o $@ $^
+
+PHONY: clean run
+
+run: $(PROG)
+ ./$(PROG)
+
+clean:
+ rm -f *.o
+ rm -f $(TRASH)
+
diff --git a/sem3/osc/mm11/regn/regn.l b/sem3/osc/mm11/regn/regn.l
new file mode 100644
index 0000000..bbaadb8
--- /dev/null
+++ b/sem3/osc/mm11/regn/regn.l
@@ -0,0 +1,40 @@
+%{
+#include <math.h>
+#include <string.h>
+#include "symtab.h"
+#include "regn.tab.h"
+%}
+
+realtal ([0-9]+|([0-9]*\.[0-9]+))([eE][-+]?[0-9]+)?
+var_begin let
+op_log log
+op_exp exp
+op_sqrt sqrt
+var [A-Za-z][A-Za-z0-9]*
+
+%%
+{realtal} {yylval.dval = atof(yytext);
+ return TAL;}
+{var_begin} {return VAR_BEGIN;}
+{op_log} {return LOG;}
+{op_exp} {return EXP;}
+{op_sqrt} {return SQRT;}
+
+{var} {yylval.string = strdup(yytext); return VAR;}
+
+[ \t] ;
+
+
+'$' {return 0;}
+
+\n|. {return yytext[0];}
+
+%%
+
+void init_sym()
+{
+ int i;
+ for (i = 0; i < HASHSIZE; i++)
+ symbolarray[i] = NULL;
+}
+
diff --git a/sem3/osc/mm11/regn/regn.y b/sem3/osc/mm11/regn/regn.y
new file mode 100644
index 0000000..d0f67eb
--- /dev/null
+++ b/sem3/osc/mm11/regn/regn.y
@@ -0,0 +1,54 @@
+%{
+#include <stdio.h>
+#include <math.h>
+#include "symtab.h"
+#include <string.h>
+%}
+
+%union {
+ char *string;
+ double dval;
+}
+
+%token <string> VAR
+%token <dval> TAL
+%token LOG EXP SQRT VAR_BEGIN
+
+%left '-' '+'
+%right LOG EXP SQRT
+%left '*' '/'
+%right UMINUS
+
+%type <dval> expression
+
+%%
+
+statement_list: statement '\n'
+ | statement_list statement '\n' ;
+
+statement: expression {printf("= %f\n",$1);}
+ | VAR_BEGIN VAR '=' expression {symnode_t *n = sym_lookup($2);
+ if( !n ) {n = sym_insert($2); }
+ n->value = $4;};
+
+expression: expression '+' expression {$$ = $1 + $3;}
+ | expression '-' expression {$$ = $1 - $3;}
+ | expression '*' expression {$$ = $1 * $3;}
+ | expression '/' expression {if ($3 == 0.0)
+ yyerror("divide dy zero");
+ else $$ = $1 / $3;}
+ | '-' expression %prec UMINUS {$$ = - $2;}
+ | '(' expression ')' {$$= $2;}
+ | LOG expression {$$ = log($2);}
+ | EXP expression {$$ = exp($2);}
+ | SQRT expression {$$ = sqrt($2);}
+ | TAL {$$ = $1;}
+ | VAR {symnode_t *n = sym_lookup($1);
+ if( !n ) { yyerror("Var not found"); } else { $$ = n->value;} };
+%%
+
+int main()
+{
+ yyparse();
+}
+
diff --git a/sem3/osc/mm11/regn/symtab.c b/sem3/osc/mm11/regn/symtab.c
new file mode 100644
index 0000000..8103203
--- /dev/null
+++ b/sem3/osc/mm11/regn/symtab.c
@@ -0,0 +1,50 @@
+#include "symtab.h"
+#include <stdlib.h>
+#include <string.h>
+
+unsigned int hash(char *s) {
+ uint32_t hv = 0;
+ for( int i = 0; s[i] != '\0'; i++ ) {
+ // take MSB 6 bits of hv and xors with LSB of s[i]
+ uint32_t v = ( hv >> 26 ) ^ (s[i] & 0x3f);
+
+ // Push those back on hv
+ hv = (hv << 4) | v;
+ }
+ // Return appropriate size
+ return hv % HASHSIZE;
+}
+
+
+symnode_t *sym_insert(char *var) {
+ unsigned int index = hash(var);
+
+ // Save old value
+ symnode_t *oldSym = symbolarray[index];
+
+ // Make new
+ symbolarray[index] = malloc(sizeof(symnode_t));
+ if( symbolarray[index] == NULL ) {
+ // If malloc failed
+ symbolarray[index] = oldSym;
+ return NULL;
+ }
+
+ // Link old one
+ symbolarray[index]->next = oldSym;
+ symbolarray[index]->name = var;
+
+ return symbolarray[index];
+}
+
+symnode_t *sym_lookup(char *var) {
+ unsigned int index = hash(var);
+ symnode_t *n = symbolarray[index];
+
+ // Look trough list
+ while(n != NULL && strcmp(n->name, var) != 0) {
+ n = n->next;
+ }
+
+ return n;
+}
diff --git a/sem3/osc/mm11/regn/symtab.h b/sem3/osc/mm11/regn/symtab.h
new file mode 100644
index 0000000..c61f3a8
--- /dev/null
+++ b/sem3/osc/mm11/regn/symtab.h
@@ -0,0 +1,20 @@
+#include <stdint.h>
+#define HASHSIZE 100
+
+typedef struct symnode_struct {
+ char *name;
+ struct symnode_struct *next;
+ double value;
+} symnode_t;
+
+symnode_t *sym_insert(char *var);
+symnode_t *sym_lookup(char *var);
+
+struct symnode {
+ struct symnode *next;
+ char *name;
+ int type;
+ double value;
+};
+
+symnode_t *symbolarray[HASHSIZE];
diff --git a/sem3/osc/mm11/regn2/Makefile b/sem3/osc/mm11/regn2/Makefile
new file mode 100644
index 0000000..9640aaa
--- /dev/null
+++ b/sem3/osc/mm11/regn2/Makefile
@@ -0,0 +1,30 @@
+
+LEX=flex
+YACC=bison
+LIBS=-ly -lfl -lm
+CC=gcc
+
+PROG=regn
+TRASH=lex.yy.c $(PROG).tab.c $(PROG) $(PROG).tab.h $(PROG).output
+
+$(PROG): $(PROG).tab.o lex.yy.o
+ $(CC) -o $@ $^ $(LIBS)
+
+$(PROG).tab.c $(PROG).tab.h: $(PROG).y
+ $(YACC) -d -v $(PROG).y
+
+lex.yy.c: $(PROG).l
+ $(LEX) $(PROG).l
+
+%.o: %.c
+ $(CC) -c -o $@ $^
+
+PHONY: clean run
+
+run: $(PROG)
+ ./$(PROG)
+
+clean:
+ rm -f *.o
+ rm -f $(TRASH)
+
diff --git a/sem3/osc/mm11/regn2/regn.l b/sem3/osc/mm11/regn2/regn.l
new file mode 100644
index 0000000..9988ddd
--- /dev/null
+++ b/sem3/osc/mm11/regn2/regn.l
@@ -0,0 +1,27 @@
+%{
+#include <math.h>
+#include <string.h>
+#include "regn.tab.h"
+%}
+
+realtal ([0-9]+|([0-9]*\.[0-9]+))([eE][-+]?[0-9]+)?
+op_log log
+op_exp exp
+op_sqrt sqrt
+
+%%
+{realtal} {yylval.dval = atof(yytext);
+ return TAL;}
+{op_log} {return LOG;}
+{op_exp} {return EXP;}
+{op_sqrt} {return SQRT;}
+
+[ \t] ;
+
+
+'$' {return 0;}
+
+\n|. {return yytext[0];}
+
+%%
+
diff --git a/sem3/osc/mm11/regn2/regn.y b/sem3/osc/mm11/regn2/regn.y
new file mode 100644
index 0000000..eac24c8
--- /dev/null
+++ b/sem3/osc/mm11/regn2/regn.y
@@ -0,0 +1,46 @@
+%{
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+%}
+
+%union {
+ double dval;
+}
+
+%token <dval> TAL
+%token LOG EXP SQRT
+
+%left '-' '+'
+%left LOG EXP SQRT
+%left '*' '/'
+%right UMINUS
+
+%type <dval> expression
+
+%%
+
+statement_list: statement '\n'
+ | statement_list statement '\n' ;
+
+statement: expression {printf("out \n");};
+
+expression: expression '+' expression {printf("sum \n");}
+ | expression '-' expression {printf("sub \n");}
+ | expression '*' expression {printf("mul \n");}
+ | expression '/' expression {if ($3 == 0.0)
+ yyerror("divide dy zero");
+ else printf("div \n");}
+ | '-' expression %prec UMINUS {printf("neg \n");}
+ | '(' expression ')' {;}
+ | LOG expression {printf("log \n");}
+ | EXP expression {printf("exp \n");}
+ | SQRT expression {printf("sqrt \n");}
+ | TAL {printf("load %f \n", $$);};
+%%
+
+int main()
+{
+ yyparse();
+}
+