ratio

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 474200046322ff9e4591e30137ab3eb09dfb8d36
Author: William Casarin <jb55@jb55.com>
Date:   Fri, 29 Sep 2017 20:19:55 -0700

initial commit

Diffstat:
A.gitignore | 4++++
AMakefile | 16++++++++++++++++
Alexer.l | 32++++++++++++++++++++++++++++++++
Aparser.y | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aratio.h | 7+++++++
5 files changed, 122 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,4 @@ +*.o +*.tab.* +/lex.yy.c +/ratio diff --git a/Makefile b/Makefile @@ -0,0 +1,16 @@ + +GEN=parser.tab.c parser.tab.h lex.yy.c + +all: ratio + +parser.tab.c parser.tab.h: parser.y + bison -d parser.y + +lex.yy.c: lexer.l parser.tab.h + flex lexer.l + +ratio: $(GEN) + $(CC) -o $@ -lgmp parser.tab.c lex.yy.c + +clean: + rm -f $(GEN) diff --git a/lexer.l b/lexer.l @@ -0,0 +1,32 @@ +%option noyywrap + +%{ +#include <stdio.h> +#include <gmp.h> +#include "ratio.h" + +#define YY_DECL int yylex() + +#include "parser.tab.h" + +%} + +%% + +[ \t] ; // ignore all whitespace +[0-9]+ { + mpz_t i; mpz_init(i); + mpq_init(yylval.rval); + mpz_set_str(i, yytext, 10); + mpq_set_z(yylval.rval, i); + return T_RATIO; +} +\n {return T_NEWLINE;} +"+" {return T_PLUS;} +"-" {return T_MINUS;} +"*" {return T_MULTIPLY;} +"/" {return T_DIVIDE;} +"(" {return T_LEFT;} +")" {return T_RIGHT;} + +%% diff --git a/parser.y b/parser.y @@ -0,0 +1,63 @@ +%{ + +#include <stdio.h> +#include <gmp.h> +#include <stdlib.h> + +extern int yylex(); +extern int yyparse(); +extern FILE* yyin; + +char buffer[255]; + +void yyerror(const char* s); +%} + +%union { + mpq_t rval; +} + +%token<rval> T_RATIO +%token T_PLUS T_MINUS T_MULTIPLY T_DIVIDE T_LEFT T_RIGHT +%token T_NEWLINE T_QUIT +%left T_PLUS T_MINUS +%left T_MULTIPLY T_DIVIDE + +%type<rval> expr + +%start calc + +%% + +calc: + | calc line +; + +line: T_NEWLINE + | expr T_NEWLINE { mpq_out_str(stdout, 10, $1); printf("\n"); } +; + +expr: T_RATIO { mpq_set($$, $1); } + | expr T_PLUS expr { mpq_add($$, $1, $3); } + | expr T_MINUS expr { mpq_sub($$, $1, $3); } + | expr T_MULTIPLY expr { mpq_mul($$, $1, $3); } + | expr T_DIVIDE expr { mpq_div($$, $1, $3); } + | T_LEFT expr T_RIGHT { mpq_set($$, $2); } +; + +%% + +int main() { + yyin = stdin; + + do { + yyparse(); + } while(!feof(yyin)); + + return 0; +} + +void yyerror(const char* s) { + fprintf(stderr, "Parse error: %s\n", s); + exit(1); +} diff --git a/ratio.h b/ratio.h @@ -0,0 +1,7 @@ +#include <gmp.h> + +void fresh_ratio(mpq_t r); +void fresh_bigint(mpz_t i); + +void note_mpq(const mpq_t a); +void note_mpz(const mpz_t a);