From 01255082a6fe008607a6cbfdfde509aef7011c7b Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 7 Jun 2020 08:21:22 -0400 Subject: [PATCH] Internals: Refactor to decouple LinkDot from ParseImp. No functional change intended. --- src/V3LinkDot.cpp | 3 +-- src/V3ParseImp.cpp | 22 ---------------------- src/V3ParseImp.h | 1 - src/V3String.cpp | 18 ++++++++++++++++++ src/V3String.h | 2 ++ src/verilog.l | 16 +++++++++++++--- 6 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index df2da2803..b5a9f03c3 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -67,7 +67,6 @@ #include "V3SymTable.h" #include "V3Graph.h" #include "V3Ast.h" -#include "V3ParseImp.h" #include "V3String.h" #include @@ -719,7 +718,7 @@ class LinkDotFindVisitor : public AstNVisitor { return new AstConst(fl, AstConst::VerilogStringLiteral(), v); } else if (literal.find_first_of(".eEpP") != string::npos) { // This may be a real - double v = V3ParseImp::parseDouble(literal.c_str(), literal.length(), &success); + double v = VString::parseDouble(literal, &success); if (success) return new AstConst(fl, AstConst::RealDouble(), v); } if (!success) { diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index ccf4937b6..6b7521e85 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -187,28 +187,6 @@ void V3ParseImp::tag(const char* text) { } } -double V3ParseImp::parseDouble(const char* textp, size_t length, bool* successp) { - char* strgp = new char[length + 1]; - char* dp = strgp; - if (successp) *successp = true; - for (const char* sp = textp; sp < (textp + length); ++sp) { - if (*sp != '_') *dp++ = *sp; - } - *dp++ = '\0'; - char* endp = strgp; - double d = strtod(strgp, &endp); - size_t parsed_len = endp - strgp; - if (parsed_len != strlen(strgp)) { - if (successp) { - *successp = false; - } else { - yyerrorf("Syntax error parsing real: %s", strgp); - } - } - VL_DO_DANGLING(delete[] strgp, strgp); - return d; -} - double V3ParseImp::parseTimenum(const char* textp) { size_t length = strlen(textp); char* strgp = new char[length + 1]; diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 3441cc1c4..40eeb53b9 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -162,7 +162,6 @@ public: VTimescale timeLastUnit() const { return m_timeLastUnit; } static double parseTimenum(const char* text); - static double parseDouble(const char* text, size_t length, bool* successp = NULL); void pushBeginKeywords(int state) { m_inBeginKwd++; m_lastVerilogState = state; diff --git a/src/V3String.cpp b/src/V3String.cpp index 3433306a6..d93b388dc 100644 --- a/src/V3String.cpp +++ b/src/V3String.cpp @@ -121,6 +121,24 @@ bool VString::isWhitespace(const string& str) { return true; } +double VString::parseDouble(const string& str, bool* successp) { + char* strgp = new char[str.size() + 1]; + char* dp = strgp; + if (successp) *successp = true; + for (const char* sp = str.c_str(); *sp; ++sp) { + if (*sp != '_') *dp++ = *sp; + } + *dp++ = '\0'; + char* endp = strgp; + double d = strtod(strgp, &endp); + size_t parsed_len = endp - strgp; + if (parsed_len != strlen(strgp)) { + if (successp) *successp = false; + } + VL_DO_DANGLING(delete[] strgp, strgp); + return d; +} + //###################################################################### // VHashSha256 diff --git a/src/V3String.h b/src/V3String.h index 50a725dbd..a3472c3f7 100644 --- a/src/V3String.h +++ b/src/V3String.h @@ -89,6 +89,8 @@ public: static string removeWhitespace(const string& str); // Return true if only whitespace or "" static bool isWhitespace(const string& str); + // Return double by parsing string + static double parseDouble(const string& str, bool* successp); }; //###################################################################### diff --git a/src/verilog.l b/src/verilog.l index 038d4f577..806cd4d08 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -33,7 +33,6 @@ extern void yyerrorf(const char* format, ...); #define STATE_VERILOG_RECENT S17 // State name for most recent Verilog Version #define PARSEP V3ParseImp::parsep() -#define SYMP PARSEP->symp() #define YY_INPUT(buf, result, max_size) \ do { result = PARSEP->flexPpInputToLex(buf, max_size); } while (false) @@ -91,6 +90,16 @@ void yyerrorf(const char* format, ...) { yyerror(msg); } +//====================================================================== + +static double lexParseDouble(const char* textp, size_t length) { + string text = std::string(textp, length); + bool success = false; + double d = VString::parseDouble(text, &success); + if (!success) yyerrorf("Syntax error parsing real: %s", text.c_str()); + return d; +} + // clang-format off /**********************************************************************/ %} @@ -887,11 +896,12 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} return yaINTNUM; } [0-9][_0-9]*(\.[_0-9]+)([eE][-+]?[_0-9]+)? { - FL; yylval.cdouble = PARSEP->parseDouble(yytext, yyleng); + FL; bool ok; + yylval.cdouble = lexParseDouble(yytext, yyleng); return yaFLOATNUM; } [0-9][_0-9]*(\.[_0-9]+)?([eE][-+]?[_0-9]+) { - FL; yylval.cdouble = PARSEP->parseDouble(yytext, yyleng); + FL; yylval.cdouble = lexParseDouble(yytext, yyleng); return yaFLOATNUM; } [0-9][_0-9]*(\.[_0-9]+)?(fs|ps|ns|us|ms|s) {