diff --git a/lab9/Makefile b/lab9/Makefile new file mode 100644 index 0000000..8201bd0 --- /dev/null +++ b/lab9/Makefile @@ -0,0 +1,11 @@ +expr_bison: + flex lex.l && bison -t -d syntax.y + gcc syntax.tab.c -lfl -ly -shared -fPIC -o libexpr.so + @echo "\e[92mTesting BISON implementation...\e[0m" + @python3 expr_test.py ||: +expr_stack: + gcc stack.c -shared -fPIC -o libexpr.so + @echo "\e[92mTesting STACK implementation...\e[0m" + @python3 expr_test.py ||: +clean: + @rm -f lex.yy.c syntax.tab.* *.out *.so diff --git a/lab9/expr_test.py b/lab9/expr_test.py new file mode 100644 index 0000000..1000b2e --- /dev/null +++ b/lab9/expr_test.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +# encoding: utf-8 + +import ctypes +import os + + +cwd = os.getcwd() +lib_path = os.path.join(cwd, 'libexpr.so') +lib = ctypes.cdll.LoadLibrary(lib_path) + +def convert(expr): + func = lib.convert + func.restype = ctypes.c_char_p + expr_b = expr.encode() + expr_buf = ctypes.c_char_p(expr_b) + return func(expr_buf).decode() + + +assert convert('5')=='5', convert('5') + +assert convert('9-5+2')=='95-2+', convert('9-5+2') + +print("Testing completed.") + diff --git a/lab9/lex.l b/lab9/lex.l new file mode 100644 index 0000000..9c92044 --- /dev/null +++ b/lab9/lex.l @@ -0,0 +1,12 @@ +%{ + #include"syntax.tab.h" +%} +%% +[0-9] { + yylval = (char*)malloc(2); + memcpy(yylval, yytext, 2); + return TERM; +} +"+" { yylval = "+"; return ADD; } +"-" { yylval = "-"; return SUB; } +. { /* do nothing */ } diff --git a/lab9/stack.c b/lab9/stack.c new file mode 100644 index 0000000..759b535 --- /dev/null +++ b/lab9/stack.c @@ -0,0 +1,39 @@ +#include +#include +#include +#define STACK_LEN 32 + +char *convert(char *expr){ + char opstack[STACK_LEN]; + char stack[STACK_LEN]; + int optop, top; + char *c, *ret; + + memset(opstack, '\0', STACK_LEN); + memset(stack, '\0', STACK_LEN); + optop = top = 0; + c = expr; + + while(*c != '\0'){ + if((*c >= '0') && (*c <= '9')){ + + } + else if((*c == '+') || (*c == '-')){ + + } + else{ + // lexical errors + } + c++; + } + + ret = (char*)malloc(strlen(stack)+1); + sprintf(ret, "%s", stack); + return ret; +} + +int main(){ + puts( convert("3-7+4-5") ); + return 0; +} + diff --git a/lab9/syntax.y b/lab9/syntax.y new file mode 100644 index 0000000..730d0df --- /dev/null +++ b/lab9/syntax.y @@ -0,0 +1,32 @@ +%{ + #include"lex.yy.c" + void yyerror(char*s){} + + /* + * We make assumptions on the input: + * there are no syntax errors, and + * only consist two operators, plus + * and minus, and all numbers contain + * exactly one digit, no spaces. + */ + + // where reverse Polish notation goes + char *result; +%} +%define api.value.type { char* } +%token TERM ADD SUB + +%% +Eval: Expr { result = $1; } +Expr: TERM /* write the */ + | Expr ADD TERM /* SDT actions */ + | Expr SUB TERM /* at HERE */ +%% + +char *convert(char *expr){ + YY_BUFFER_STATE buf; + buf = yy_scan_string(expr); + yyparse(); + yy_delete_buffer(buf); + return result; +}