[gcalctool] Made parser reentrant and part of MP code (Robert Ancell)



commit cbbf4c6e1b894fe695367efd78bb148aa927f467
Author: Robert Ancell <robert ancell gmail com>
Date:   Fri May 15 10:17:26 2009 +1000

    Made parser reentrant and part of MP code (Robert Ancell)
---
 ChangeLog                                          |    4 ++
 po/POTFILES.in                                     |   23 +++++----
 src/.gitignore                                     |    4 +-
 src/Makefile.am                                    |   33 ++++++------
 ...mp-equation-tokeniser.l => mp-equation-lexer.l} |   48 +++++++-----------
 src/mp-equation-parser.y                           |   52 ++++++++-----------
 src/mp-equation.c                                  |   33 ++++++++-----
 src/mp-equation.h                                  |   28 ++---------
 8 files changed, 100 insertions(+), 125 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 47a6179..9c71bd1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,10 @@
 gcalctool change history.
 =========================
 
+2009-05-15 Robert Ancell <robert ancell gmail com>
+
+    * Made parser reentrant and part of MP code (Robert Ancell)
+
 2009-05-11 Robert Ancell <robert ancell gmail com>
 
     * Really fix the license text in the about dialog (Robert Ancell, Bug #579174)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index d17826a..56d042e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -5,14 +5,15 @@
 [type: gettext/glade]data/gcalctool.ui
 data/gcalctool.desktop.in
 data/gcalctool.schemas.in
-gcalctool/calctool.c
-gcalctool/display.c
-gcalctool/dsfuns.c
-gcalctool/functions.c
-gcalctool/get.c
-gcalctool/gtk.c
-gcalctool/mp.c
-gcalctool/mp-convert.c
-gcalctool/mp-trigonometric.c
-gcalctool/mp-binary.c
-gcalctool/register.c
+src/calctool.c
+src/display.c
+src/financial.c
+src/functions.c
+src/get.c
+src/gtk.c
+src/mp.c
+src/mp-binary.c
+src/mp-convert.c
+src/mp-equation.c
+src/mp-trigonometric.c
+src/register.c
diff --git a/src/.gitignore b/src/.gitignore
index 83ef840..fc7f3f6 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,6 +1,6 @@
 .deps
-ce_parser.tab.c
-ce_parser.tab.h
+mp-equation-lexer.[ch]
+mp-equation-parser.[ch]
 gcalctool
 lex.ce.c
 libparser.a
diff --git a/src/Makefile.am b/src/Makefile.am
index f9a13f2..688b37a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -30,7 +30,10 @@ gcalctool_SOURCES = \
 	mp-trigonometric.c \
 	mp-equation.c \
 	mp-equation.h \
-	mp-equation.tab.h \	
+	mp-equation-lexer.c \
+	mp-equation-lexer.h \
+	mp-equation-parser.c \
+	mp-equation-parser.h \
 	financial.c \
 	financial.h \
 	register.c \
@@ -41,9 +44,10 @@ gcalctool_SOURCES = \
 	unittest.h
 	
 CLEANFILES = \
-	mp-equation-parser.tab.h \
-	mp-equation-parser.tab.c \
+	mp-equation-parser.h \
+	mp-equation-parser.c \
 	mp-equation-lexer.c \
+	mp-equation-lexer.h \
 	libparser.a
 
 gcalctool_LDADD = \
@@ -54,25 +58,20 @@ gcalctool_LDADD = \
 
 libparser.a: \
 	mp-equation-lexer.o\
-	mp-equation-parser.tab.o\
+	mp-equation-parser.o\
 	mp-equation.o
 	$(AR) r libparser.a $^
 	$(RANLIB) libparser.a
 
-mp-equation.o: mp-equation.c mp-equation.h calctool.h
-	$(COMPILE) -c $(INCLUDES) -o $@ $(srcdir)/mp-equation.c
-
-mp-equation-lexer.o: mp-equation-lexer.c calctool.h
-	$(COMPILE) -c $(INCLUDES) -o $@ mp-equation-lexer.c
-
-mp-equation-parser.tab.o: mp-equation-parser.tab.c
-	$(COMPILE) -c $(INCLUDES) -o $@ mp-equation-parser.tab.c
+mp-equation-parser.c mp-equation-parser.h: mp-equation-parser.y
+	bison -d -o mp-equation-parser.c $(srcdir)/mp-equation-parser.y
 
-mp-equation-parser.tab.c: mp-equation-parser.y calctool.h
-	bison -d -p ce -d $(srcdir)/mp-equation-parser.y
+mp-equation-lexer.c mp-equation-lexer.h: mp-equation-lexer.l
+	$(LEX) $(srcdir)/mp-equation-lexer.l
 
-mp-equation-lexer.c: mp-equation-parser.tab.c mp-equation-tokeniser.l
-	$(LEX) -Pce -o $@ $(srcdir)/mp-equation-tokeniser.l
+mp-equation-parser.o: mp-equation-lexer.h
+mp-equation-lexer.o: mp-equation-parser.h
+mp-equation.c: mp-equation-lexer.h mp-equation-parser.h
 
 code-format: 
 	ls *[ch] | xargs indent -nbad -bap -bbo -nbc -br\
@@ -92,7 +91,7 @@ uninstall-local:
 
 EXTRA_DIST = \
 	mp-equation-parser.y \
-	mp-equation-tokeniser.l
+	mp-equation-lexer.l
 
 test: gcalctool
 	./gcalctool -u
diff --git a/src/mp-equation-tokeniser.l b/src/mp-equation-lexer.l
similarity index 74%
rename from src/mp-equation-tokeniser.l
rename to src/mp-equation-lexer.l
index e568280..f8fc4d2 100644
--- a/src/mp-equation-tokeniser.l
+++ b/src/mp-equation-lexer.l
@@ -1,4 +1,9 @@
-%option noyywrap
+%option 8bit reentrant bison-locations
+%option never-interactive
+%option noyywrap noinput nounput
+%option prefix="_mp_equation_"
+%option extra-type="MPEquationParserState *"
+%option outfile="mp-equation-lexer.c" header-file="mp-equation-lexer.h"
 
 %{
 
@@ -29,12 +34,9 @@
 
 #include "calctool.h"
 #include "mp-equation.h"
-#include "mp-equation-parser.tab.h"
+#include "mp-equation-parser.h"
 %}
 
-%option noinput
-%option nounput
-
 DECIMAL	"."|","
 SIGN	"+"|"-" 
 CHARACTER [a-z]|[A-Z]
@@ -89,43 +91,43 @@ BIN_NUM{BIN}+|{BIN}*{DECIMAL}{BIN}*
 "xor"|"Xor"|"XOR" {return tXOR;}
 
 "R"{DEC}+ {
-celval.integer = atoi(yytext+1);  
+yylval->integer = atoi(yytext+1);  
 return tREG;
 }
 
 
 {DEC_NUM}{EXP}{DEC_NUM} {
 if (v->base == HEX) REJECT;
-if (strlen(yytext) > MAX_DIGITS) parser_state.error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, basevals[v->base], &celval.int_t);
+if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
+mp_set_from_string(yytext, basevals[v->base], &yylval->int_t);
 return tNUMBER;
 }
 
 {BIN_NUM} {
 if (v->base != BIN) REJECT;
-if (strlen(yytext) > MAX_DIGITS) parser_state.error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, basevals[v->base], &celval.int_t);
+if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
+mp_set_from_string(yytext, basevals[v->base], &yylval->int_t);
 return tNUMBER;
 }
 
 {OCT_NUM} {
 if (v->base != OCT) REJECT;
-if (strlen(yytext) > MAX_DIGITS) parser_state.error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, basevals[v->base], &celval.int_t);
+if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
+mp_set_from_string(yytext, basevals[v->base], &yylval->int_t);
 return tNUMBER;
 }
 
 {DEC_NUM} {
 if (v->base != DEC) REJECT;
-if (strlen(yytext) > MAX_DIGITS) parser_state.error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, basevals[v->base], &celval.int_t);
+if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
+mp_set_from_string(yytext, basevals[v->base], &yylval->int_t);
 return tNUMBER;
 }
 
 {HEX_NUM} {
 if (v->base != HEX) REJECT;
-if (strlen(yytext) > MAX_DIGITS) parser_state.error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, basevals[v->base], &celval.int_t);
+if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
+mp_set_from_string(yytext, basevals[v->base], &yylval->int_t);
 return tNUMBER;
 }
 
@@ -134,17 +136,3 @@ return tNUMBER;
 .        {return *yytext; }
 
 %% 
-
-void
-reset_ce_tokeniser()
-{
-ce_flush_buffer(YY_CURRENT_BUFFER);
-
-}
-
-#if 0
-// EMPTY BLOCK
-
-
-
-#endif
diff --git a/src/mp-equation-parser.y b/src/mp-equation-parser.y
index 114a5fa..7f5ad70 100644
--- a/src/mp-equation-parser.y
+++ b/src/mp-equation-parser.y
@@ -28,9 +28,16 @@
 #include "calctool.h"
 #include "register.h"
 #include "mp-equation.h"
-
+#include "mp-equation-parser.h"
+#include "mp-equation-lexer.h"
 %}
 
+%define api.pure
+%name-prefix "_mp_equation_"
+%locations
+%parse-param {yyscan_t yyscanner}
+%lex-param {yyscan_t yyscanner}
+
 %union {
   MPNumber int_t;
   int integer;
@@ -97,11 +104,9 @@
 
 statement: 
   seq
-| value { mp_set_from_mp(&$1, &parser_state.ret); parser_state.flags |= ANS; }
+| value { mp_set_from_mp(&$1, &((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->ret); ((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->flags |= ANS; }
 | error {
-  yyclearin; 
-  reset_ce_tokeniser();
-  parser_state.error = -EINVAL; 
+  ((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->error = -EINVAL; 
   YYABORT;
 }
 ;
@@ -141,35 +146,35 @@ exp:
 
 | exp tMOD exp %prec MED {
     if (!mp_is_integer(&$1) || !mp_is_integer(&$3)) {
-	parser_state.error = -PARSER_ERR_MODULUSOP;
+	((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_MODULUSOP;
     } else {
       if (mp_modulus_divide(&$1, &$3, &$$)) {
-        parser_state.error = -EINVAL;
+        ((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->error = -EINVAL;
       }			   
     }
 }
 
 | exp tAND exp {
     if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
-	parser_state.error = -PARSER_ERR_BITWISEOP;
+	((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
     }
     mp_and(&$1, &$3, &$$);
 }
 | exp tOR exp {
     if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
-	parser_state.error = -PARSER_ERR_BITWISEOP;
+	((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
     }
     mp_or(&$1, &$3, &$$);
 }
 | exp tXNOR exp {
     if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
-	parser_state.error = -PARSER_ERR_BITWISEOP;
+	((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
     }
     mp_xnor(&$1, &$3, v->wordlen, &$$);
 }
 | exp tXOR exp {
     if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
-	parser_state.error = -PARSER_ERR_BITWISEOP;
+	((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
     }
     mp_xor(&$1, &$3, &$$);
 }
@@ -186,9 +191,9 @@ term:
 | term '%' {mp_divide_integer(&$1, 100, &$$);}
 | '~' term %prec LNEG {
     if (!mp_is_natural(&$2)) {
-	parser_state.error = -PARSER_ERR_BITWISEOP;
+	((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
     } else if (!mp_is_overflow(&$2, v->wordlen)) {
-	parser_state.error = -PARSER_ERR_OVERFLOW;
+	((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_OVERFLOW;
     }
     mp_not(&$2, v->wordlen, &$$);
 }
@@ -237,17 +242,17 @@ func:
 | tTRUNC term %prec HIGH {mp_mask(&$2, v->wordlen, &$$);}
 | t1S term %prec HIGH  {
     if (!mp_is_natural(&$2)) {
-	parser_state.error = -PARSER_ERR_BITWISEOP;
+	((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
     } else if (!mp_is_overflow(&$2, v->wordlen)) {
-	parser_state.error = -PARSER_ERR_OVERFLOW;
+	((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_OVERFLOW;
     }
     mp_1s_complement(&$2, v->wordlen, &$$);
 }
 | t2S term %prec HIGH {
     if (!mp_is_natural(&$2)) {
-	parser_state.error = -PARSER_ERR_BITWISEOP;
+	((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
     } else if (!mp_is_overflow(&$2, v->wordlen)) {
-	parser_state.error = -PARSER_ERR_OVERFLOW;
+	((MPEquationParserState *)_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_OVERFLOW;
     }
     mp_2s_complement(&$2, v->wordlen, &$$);
 }
@@ -268,16 +273,3 @@ number:
 ;
 
 %%
-
-int ceerror(char *s)
-{
-  return 0;
-}
-
-#if 0
-
-| '(' lexp ')' {mp_set_from_mp(&$2, &$$);}
-
-| term term {mp_multiply(&$1, &$2, &$$);}
-
-#endif
diff --git a/src/mp-equation.c b/src/mp-equation.c
index 2a2132e..ad768f1 100644
--- a/src/mp-equation.c
+++ b/src/mp-equation.c
@@ -20,29 +20,33 @@
  */
 
 #include "mp-equation.h"
-#include "limits.h"
 #include "calctool.h"
+#include "mp-equation-parser.h"
+#include "mp-equation-lexer.h"
 
-struct parser_state parser_state;
+extern int _mp_equation_parse(yyscan_t yyscanner);
 
 int 
 mp_equation_parse_(const char *expression, MPNumber *result, int flags)
 {
     int ret = 0;
+    MPEquationParserState parser_state;
+    yyscan_t yyscanner;
+    YY_BUFFER_STATE buffer;
 
-    if (!(expression && result)) {
+    if (!(expression && result) || strlen(expression) == 0)
         return(-EINVAL);
-    }
 
-    memset(&parser_state, 0, sizeof(struct parser_state));
+    memset(&parser_state, 0, sizeof(MPEquationParserState));
+    v->math_error = 0;
+        
+    _mp_equation_lex_init_extra(&parser_state, &yyscanner);
+    buffer = _mp_equation__scan_string(expression, yyscanner);
 
-    if (strlen(expression)) {
-        parser_state.i = 0;
-        parser_state.buff = strdup(expression);
-        v->math_error = 0;
-        ret = ceparse();
-        free(parser_state.buff);
-    }
+    ret = _mp_equation_parse(yyscanner);
+
+    _mp_equation__delete_buffer(buffer, yyscanner);
+    _mp_equation_lex_destroy(yyscanner);
 
     ret = (parser_state.error) ? parser_state.error : ret;
 
@@ -79,3 +83,8 @@ mp_equation_udf_parse(const char *expression)
     MPNumber t;
     return(mp_equation_parse_(expression, &t, 0));
 }
+
+int _mp_equation_error(void *yylloc, MPEquationParserState *state, char *text)
+{
+  return 0;
+}
diff --git a/src/mp-equation.h b/src/mp-equation.h
index f698c30..a8f0aa1 100644
--- a/src/mp-equation.h
+++ b/src/mp-equation.h
@@ -31,17 +31,6 @@
 
 #include "mp.h"
 
-#define PARSER_MIN(a, b) (a < b) ? a : b;
-
-#define YY_INPUT(buf, result, max) {\
-    int l = strlen(parser_state.buff);\
-    int remaining = l - parser_state.i;\
-    int c = PARSER_MIN(remaining, max);\
-    memcpy(buf, parser_state.buff + parser_state.i, c);\
-    parser_state.i += c;\
-    result = (c) ? c : YY_NULL;\
-}
-
 #define ANS 1
 
 #define PARSER_ERR_INVALID_BASE     10000
@@ -50,24 +39,17 @@
 #define PARSER_ERR_MODULUSOP        10003
 #define PARSER_ERR_OVERFLOW         10004
 
-struct parser_state {
+typedef struct {
     int flags;
-    char *buff;
-    int i;
+
     int error;
-    MPNumber ret;
-    int ncount;
-};
 
-extern struct parser_state parser_state;
+    MPNumber ret;
+} MPEquationParserState;
 
 int mp_equation_parse(const char *expression, MPNumber *result);
 int mp_equation_udf_parse(const char *expression);
 
-int celex();
-int ceerror();                   /* dummy definition TODO: this is a douple */
-int ceparse();                   /* dummy definition. */
-int ceerror(char *s);
-void reset_ce_tokeniser();
+int _mp_equation_error(void *yylloc, MPEquationParserState *state, char *text);
 
 #endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]