diff options
Diffstat (limited to 'sem3/osc/mm11')
-rw-r--r-- | sem3/osc/mm11/opgaver.md | 32 | ||||
-rw-r--r-- | sem3/osc/mm11/regn/Makefile | 30 | ||||
-rw-r--r-- | sem3/osc/mm11/regn/regn.l | 40 | ||||
-rw-r--r-- | sem3/osc/mm11/regn/regn.y | 54 | ||||
-rw-r--r-- | sem3/osc/mm11/regn/symtab.c | 50 | ||||
-rw-r--r-- | sem3/osc/mm11/regn/symtab.h | 20 | ||||
-rw-r--r-- | sem3/osc/mm11/regn2/Makefile | 30 | ||||
-rw-r--r-- | sem3/osc/mm11/regn2/regn.l | 27 | ||||
-rw-r--r-- | sem3/osc/mm11/regn2/regn.y | 46 |
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(); +} + |