From 8412f4df29bbaede16a7f38deac363a4fbf81d89 Mon Sep 17 00:00:00 2001 From: Adrian Negreanu Date: Fri, 27 Oct 2017 17:05:10 +0300 Subject: constexp.l,y: generate a reentrant scanner and parser --- src/constexp.h | 23 +++++++++++------ src/constexp.l | 76 +++++++++++++++++++++++++++++++------------------------- src/constexp.y | 42 ++++++++++++++++++++++--------- src/cppvalue.cpp | 32 ++++++++++++------------ src/cppvalue.h | 11 ++++---- 5 files changed, 110 insertions(+), 74 deletions(-) diff --git a/src/constexp.h b/src/constexp.h index d84e94e..8bf582e 100644 --- a/src/constexp.h +++ b/src/constexp.h @@ -22,12 +22,21 @@ #include "cppvalue.h" #include -extern bool parseconstexp(const char *fileName,int line,const QCString &s); -extern int constexpYYparse(); -extern int constexpYYdebug; -extern QCString g_strToken; -extern CPPValue g_resultValue; -extern QCString g_constExpFileName; -extern int g_constExpLineNr; +#define YYSTYPE CPPValue +typedef void* yyscan_t; +struct constexpYY_state +{ + QCString g_strToken; + CPPValue g_resultValue; + int g_constExpLineNr; + QCString g_constExpFileName; + + const char *g_inputString; + int g_inputPosition; +}; +extern bool parseconstexp(const char *fileName,int line,const QCString &s); +extern int constexpYYparse(yyscan_t); +extern int constexpYYlex(YYSTYPE *lvalp, yyscan_t); +struct constexpYY_state* constexpYYget_extra (yyscan_t yyscanner ); #endif diff --git a/src/constexp.l b/src/constexp.l index aa6c4cc..f5862c7 100644 --- a/src/constexp.l +++ b/src/constexp.l @@ -18,38 +18,24 @@ %option never-interactive %option prefix="constexpYY" %option nounput +%option reentrant bison-bridge +%option extra-type="struct constexpYY_state *" %{ #include "constexp.h" #include "cppvalue.h" -#include "ce_parse.h" // generated header file +#include "ce_parse.hpp" // generated header file #include "message.h" #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 - -QCString g_strToken; -CPPValue g_resultValue; -int g_constExpLineNr; -QCString g_constExpFileName; -static const char *g_inputString; -static int g_inputPosition; -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); +static int yyread(char *buf,int max_size,yyscan_t yyscanner); -static int yyread(char *buf,int max_size) -{ - int c=0; - while( c < max_size && g_inputString[g_inputPosition] ) - { - *buf = g_inputString[g_inputPosition++] ; - c++; buf++; - } - return c; -} +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size,yyscanner); %} @@ -83,44 +69,66 @@ CONSTSUFFIX ([uU][lL]?[lL]?)|([lL][lL]?[uU]?) "(" { return TOK_LPAREN; } ")" { return TOK_RPAREN; } "'"(([^\'\n\r\\]+)|(\\(([ntvbrfa\\?'\"])|([0-9]+)|([xX][0-9a-fA-F]+))))"'" { - g_strToken=yytext; + yyextra->g_strToken=yytext; return TOK_CHARACTER; } -0[0-7]*{CONSTSUFFIX}? { g_strToken=yytext; +0[0-7]*{CONSTSUFFIX}? { yyextra->g_strToken=yytext; return TOK_OCTALINT; } -[1-9][0-9]*{CONSTSUFFIX}? { g_strToken=yytext; +[1-9][0-9]*{CONSTSUFFIX}? { yyextra->g_strToken=yytext; return TOK_DECIMALINT; } -(0x|0X)[0-9a-fA-F]+{CONSTSUFFIX}? { g_strToken=yytext+2; +(0x|0X)[0-9a-fA-F]+{CONSTSUFFIX}? { yyextra->g_strToken=yytext+2; return TOK_HEXADECIMALINT; } (([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+))([eE]([\-\+])?[0-9]+)?([fFlL])? { - g_strToken=yytext; return TOK_FLOAT; + yyextra->g_strToken=yytext; return TOK_FLOAT; } ([0-9]+[eE])([\-\+])?[0-9]+([fFlL])? { - g_strToken=yytext; return TOK_FLOAT; + yyextra->g_strToken=yytext; return TOK_FLOAT; } . \n %% +static int yyread(char *buf,int max_size,yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + int c=0; + while( c < max_size && yyextra->g_inputString[yyextra->g_inputPosition] ) + { + *buf = yyextra->g_inputString[yyextra->g_inputPosition++] ; + c++; buf++; + } + return c; +} + + +static yyscan_t yyscanner; +static struct constexpYY_state constexpYY_extra; + bool parseconstexp(const char *fileName,int lineNr,const QCString &s) { + constexpYYlex_init_extra(&constexpYY_extra, &yyscanner); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + + yyextra->g_constExpFileName = fileName; + yyextra->g_constExpLineNr = lineNr; + yyextra->g_inputString = s; + yyextra->g_inputPosition = 0; + constexpYYrestart( yyin, yyscanner ); + printlex(yy_flex_debug, TRUE, __FILE__, fileName); //printf("Expression: `%s'\n",s.data()); - g_constExpFileName = fileName; - g_constExpLineNr = lineNr; - g_inputString = s; - g_inputPosition = 0; - constexpYYrestart( constexpYYin ); - constexpYYparse(); + + constexpYYparse(yyscanner); + //printf("Result: %ld\n",(long)g_resultValue); printlex(yy_flex_debug, FALSE, __FILE__, fileName); - return (long)g_resultValue!=0; + return (long)yyextra->g_resultValue!=0; } extern "C" { - int constexpYYwrap() { return 1; } + int constexpYYwrap(yyscan_t yyscanner) { return 1; } } diff --git a/src/constexp.y b/src/constexp.y index cada993..62a51f3 100644 --- a/src/constexp.y +++ b/src/constexp.y @@ -26,24 +26,24 @@ #define MSDOS #endif -#define YYSTYPE CPPValue #include #include -int constexpYYerror(const char *s) +int constexpYYerror(yyscan_t yyscanner, const char *s) { - warn(g_constExpFileName,g_constExpLineNr, + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + warn(yyextra->g_constExpFileName, yyextra->g_constExpLineNr, "preprocessing issue while doing constant expression evaluation: %s",s); return 0; } -int constexpYYlex(); - %} -%no-lines %name-prefix "constexpYY" +%define api.pure full +%lex-param {yyscan_t yyscanner} +%parse-param {yyscan_t yyscanner} %token TOK_QUESTIONMARK %token TOK_COLON @@ -78,7 +78,10 @@ int constexpYYlex(); %% start: constant_expression - { g_resultValue = $1; return 0; } + { + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + yyextra->g_resultValue = $1; return 0; + } ; constant_expression: logical_or_expression @@ -267,15 +270,30 @@ primary_expression: constant ; constant: TOK_OCTALINT - { $$ = parseOctal(); } + { + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + $$ = parseOctal(yyextra->g_strToken); + } | TOK_DECIMALINT - { $$ = parseDecimal(); } + { + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + $$ = parseDecimal(yyextra->g_strToken); + } | TOK_HEXADECIMALINT - { $$ = parseHexadecimal(); } + { + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + $$ = parseHexadecimal(yyextra->g_strToken); + } | TOK_CHARACTER - { $$ = parseCharacter(); } + { + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + $$ = parseCharacter(yyextra->g_strToken); + } | TOK_FLOAT - { $$ = parseFloat(); } + { + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + $$ = parseFloat(yyextra->g_strToken); + } ; %% diff --git a/src/cppvalue.cpp b/src/cppvalue.cpp index 176931d..1543498 100644 --- a/src/cppvalue.cpp +++ b/src/cppvalue.cpp @@ -21,44 +21,44 @@ #include "cppvalue.h" #include "constexp.h" -CPPValue parseOctal() +CPPValue parseOctal(const QCString& token) { long val = 0; - for (const char *p = g_strToken.data(); *p != 0; p++) + for (const char *p = token.data(); *p != 0; p++) { if (*p >= '0' && *p <= '7') val = val * 8 + *p - '0'; } return CPPValue(val); } -CPPValue parseDecimal() +CPPValue parseDecimal(const QCString& token) { long val = 0; - for (const char *p = g_strToken.data(); *p != 0; p++) + for (const char *p = token.data(); *p != 0; p++) { if (*p >= '0' && *p <= '9') val = val * 10 + *p - '0'; } return CPPValue(val); } -CPPValue parseHexadecimal() +CPPValue parseHexadecimal(const QCString& token) { long val = 0; - for (const char *p = g_strToken.data(); *p != 0; p++) + for (const char *p = token.data(); *p != 0; p++) { if (*p >= '0' && *p <= '9') val = val * 16 + *p - '0'; else if (*p >= 'a' && *p <= 'f') val = val * 16 + *p - 'a' + 10; else if (*p >= 'A' && *p <= 'F') val = val * 16 + *p - 'A' + 10; } - //printf("parseHexadecimal %s->%x\n",g_strToken.data(),val); + //printf("parseHexadecimal %s->%x\n",token.data(),val); return CPPValue(val); } -CPPValue parseCharacter() // does not work for '\n' and the alike +CPPValue parseCharacter(const QCString& token) // does not work for '\n' and the alike { - if (g_strToken[1]=='\\') + if (token[1]=='\\') { - switch(g_strToken[2]) + switch(token[2]) { case 'n': return CPPValue((long)'\n'); case 't': return CPPValue((long)'\t'); @@ -79,17 +79,17 @@ CPPValue parseCharacter() // does not work for '\n' and the alike case '5': // fall through case '6': // fall through case '7': // fall through - return parseOctal(); + return parseOctal(token); case 'x': - case 'X': return parseHexadecimal(); - default: printf("Invalid escape sequence %s found!\n",g_strToken.data()); + case 'X': return parseHexadecimal(token); + default: printf("Invalid escape sequence %s found!\n",token.data()); return CPPValue(0L); } } - return CPPValue((long)g_strToken[1]); + return CPPValue((long)token[1]); } -CPPValue parseFloat() +CPPValue parseFloat(const QCString& token) { - return CPPValue(atof(g_strToken)); + return CPPValue(atof(token)); } diff --git a/src/cppvalue.h b/src/cppvalue.h index 59dd594..cde033d 100644 --- a/src/cppvalue.h +++ b/src/cppvalue.h @@ -21,6 +21,7 @@ #include #include +#include /** A class representing a C-preprocessor value. */ class CPPValue @@ -52,10 +53,10 @@ class CPPValue } v; }; -extern CPPValue parseOctal(); -extern CPPValue parseDecimal(); -extern CPPValue parseHexadecimal(); -extern CPPValue parseCharacter(); -extern CPPValue parseFloat(); +extern CPPValue parseOctal(const QCString& token); +extern CPPValue parseDecimal(const QCString& token); +extern CPPValue parseHexadecimal(const QCString& token); +extern CPPValue parseCharacter(const QCString& token); +extern CPPValue parseFloat(const QCString& token); #endif -- cgit v0.12