[gcalctool] Made parser reentrant and part of MP code (Robert Ancell)
- From: Robert Ancell <rancell src gnome org>
- To: svn-commits-list gnome org
- Subject: [gcalctool] Made parser reentrant and part of MP code (Robert Ancell)
- Date: Thu, 14 May 2009 23:51:02 -0400 (EDT)
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]