diff options
author | 2019-03-25 22:44:58 +0100 | |
---|---|---|
committer | 2019-03-25 22:44:58 +0100 | |
commit | c24473ddff715ecec2e258a6eb38960cf8c8e98e (patch) | |
tree | 8ea44b6396a6129913c0aac13859b5de9965e972 /src/lib/netlist/plib/pparser.cpp | |
parent | 009cba4fb8102102168ef32870892438327f3705 (diff) | |
parent | 598cd5227223c3b04ca31f0dbc1981256d9ea3ff (diff) |
conflict resolution (nw)
Diffstat (limited to 'src/lib/netlist/plib/pparser.cpp')
-rw-r--r-- | src/lib/netlist/plib/pparser.cpp | 278 |
1 files changed, 157 insertions, 121 deletions
diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp index 7547572192d..5e1a231da81 100644 --- a/src/lib/netlist/plib/pparser.cpp +++ b/src/lib/netlist/plib/pparser.cpp @@ -16,16 +16,6 @@ namespace plib { // A simple tokenizer // ---------------------------------------------------------------------------------------- -ptokenizer::ptokenizer(plib::putf8_reader &strm) -: m_strm(strm), m_lineno(0), m_cur_line(""), m_px(m_cur_line.begin()), m_unget(0), m_string('"') -{ -} - -ptokenizer::~ptokenizer() -{ -} - - pstring ptokenizer::currentline_str() { return m_cur_line; @@ -34,7 +24,7 @@ pstring ptokenizer::currentline_str() void ptokenizer::skipeol() { - pstring::code_t c = getc(); + pstring::value_type c = getc(); while (c) { if (c == 10) @@ -49,11 +39,11 @@ void ptokenizer::skipeol() } -pstring::code_t ptokenizer::getc() +pstring::value_type ptokenizer::getc() { if (m_unget != 0) { - pstring::code_t c = m_unget; + pstring::value_type c = m_unget; m_unget = 0; return c; } @@ -66,11 +56,11 @@ pstring::code_t ptokenizer::getc() return 0; return '\n'; } - pstring::code_t c = *(m_px++); + pstring::value_type c = *(m_px++); return c; } -void ptokenizer::ungetc(pstring::code_t c) +void ptokenizer::ungetc(pstring::value_type c) { m_unget = c; } @@ -122,6 +112,7 @@ pstring ptokenizer::get_identifier_or_number() return tok.str(); } +// FIXME: combine into template double ptokenizer::get_number_double() { token_t tok = get_token(); @@ -129,8 +120,8 @@ double ptokenizer::get_number_double() { error(pfmt("Expected a number, got <{1}>")(tok.str()) ); } - bool err = false; - double ret = tok.str().as_double(&err); + bool err; + auto ret = plib::pstonum_ne<double>(tok.str(), err); if (err) error(pfmt("Expected a number, got <{1}>")(tok.str()) ); return ret; @@ -143,8 +134,8 @@ long ptokenizer::get_number_long() { error(pfmt("Expected a long int, got <{1}>")(tok.str()) ); } - bool err = false; - long ret = tok.str().as_long(&err); + bool err; + auto ret = plib::pstonum_ne<long>(tok.str(), err); if (err) error(pfmt("Expected a long int, got <{1}>")(tok.str()) ); return ret; @@ -182,7 +173,7 @@ ptokenizer::token_t ptokenizer::get_token() ptokenizer::token_t ptokenizer::get_token_internal() { /* skip ws */ - pstring::code_t c = getc(); + pstring::value_type c = getc(); while (m_whitespace.find(c) != pstring::npos) { c = getc(); @@ -272,28 +263,31 @@ void ptokenizer::error(const pstring &errs) // A simple preprocessor // ---------------------------------------------------------------------------------------- -ppreprocessor::ppreprocessor(std::vector<define_t> *defines) -: m_ifflag(0), m_level(0), m_lineno(0) +ppreprocessor::ppreprocessor(defines_map_type *defines) +: pistream() +, m_ifflag(0) +, m_level(0) +, m_lineno(0) +, m_pos(0) +, m_state(PROCESS) +, m_comment(false) { - m_expr_sep.push_back("!"); - m_expr_sep.push_back("("); - m_expr_sep.push_back(")"); - m_expr_sep.push_back("+"); - m_expr_sep.push_back("-"); - m_expr_sep.push_back("*"); - m_expr_sep.push_back("/"); - m_expr_sep.push_back("=="); - m_expr_sep.push_back(" "); - m_expr_sep.push_back("\t"); + m_expr_sep.emplace_back("!"); + m_expr_sep.emplace_back("("); + m_expr_sep.emplace_back(")"); + m_expr_sep.emplace_back("+"); + m_expr_sep.emplace_back("-"); + m_expr_sep.emplace_back("*"); + m_expr_sep.emplace_back("/"); + m_expr_sep.emplace_back("&&"); + m_expr_sep.emplace_back("||"); + m_expr_sep.emplace_back("=="); + m_expr_sep.emplace_back(" "); + m_expr_sep.emplace_back("\t"); - m_defines.insert({"__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")}); if (defines != nullptr) - { - for (auto & p : *defines) - { - m_defines.insert({p.m_name, p}); - } - } + m_defines = *defines; + m_defines.insert({"__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")}); } void ppreprocessor::error(const pstring &err) @@ -301,35 +295,42 @@ void ppreprocessor::error(const pstring &err) throw pexception("PREPRO ERROR: " + err); } +pstream::size_type ppreprocessor::vread(value_type *buf, const pstream::size_type n) +{ + size_type bytes = std::min(m_buf.size() - m_pos, n); + + if (bytes==0) + return 0; + + std::memcpy(buf, m_buf.c_str() + m_pos, bytes); + m_pos += bytes; + return bytes; +} + +#define CHECKTOK2(p_op, p_prio) \ + else if (tok == # p_op) \ + { \ + if (prio < (p_prio)) \ + return val; \ + start++; \ + const auto v2 = expr(sexpr, start, (p_prio)); \ + val = (val p_op v2); \ + } \ +// Operator precedence see https://en.cppreference.com/w/cpp/language/operator_precedence -double ppreprocessor::expr(const std::vector<pstring> &sexpr, std::size_t &start, int prio) +int ppreprocessor::expr(const std::vector<pstring> &sexpr, std::size_t &start, int prio) { - double val; + int val = 0; pstring tok=sexpr[start]; if (tok == "(") { start++; - val = expr(sexpr, start, /*prio*/ 0); + val = expr(sexpr, start, /*prio*/ 255); if (sexpr[start] != ")") error("parsing error!"); start++; } - else if (tok == "!") - { - start++; - val = expr(sexpr, start, 90); - if (val != 0) - val = 0; - else - val = 1; - } - else - { - tok=sexpr[start]; - val = tok.as_double(); - start++; - } while (start < sexpr.size()) { tok=sexpr[start]; @@ -338,36 +339,25 @@ double ppreprocessor::expr(const std::vector<pstring> &sexpr, std::size_t &start // FIXME: catch error return val; } - else if (tok == "+") + else if (tok == "!") { - if (prio > 10) + if (prio < 3) return val; start++; - val = val + expr(sexpr, start, 10); + val = !expr(sexpr, start, 3); } - else if (tok == "-") - { - if (prio > 10) - return val; - start++; - val = val - expr(sexpr, start, 10); - } - else if (tok == "*") - { - start++; - val = val * expr(sexpr, start, 20); - } - else if (tok == "/") - { - start++; - val = val / expr(sexpr, start, 20); - } - else if (tok == "==") + CHECKTOK2(*, 5) + CHECKTOK2(/, 5) + CHECKTOK2(+, 6) + CHECKTOK2(-, 6) + CHECKTOK2(==, 10) + CHECKTOK2(&&, 14) + CHECKTOK2(||, 15) + else { - if (prio > 5) - return val; + // FIXME: error handling + val = plib::pstonum<decltype(val)>(tok); start++; - val = (val == expr(sexpr, start, 5)) ? 1.0 : 0.0; } } return val; @@ -376,10 +366,7 @@ double ppreprocessor::expr(const std::vector<pstring> &sexpr, std::size_t &start ppreprocessor::define_t *ppreprocessor::get_define(const pstring &name) { auto idx = m_defines.find(name); - if (idx != m_defines.end()) - return &idx->second; - else - return nullptr; + return (idx != m_defines.end()) ? &idx->second : nullptr; } pstring ppreprocessor::replace_macros(const pstring &line) @@ -389,78 +376,135 @@ pstring ppreprocessor::replace_macros(const pstring &line) for (auto & elem : elems) { define_t *def = get_define(elem); - if (def != nullptr) - ret += def->m_replace; - else - ret += elem; + ret += (def != nullptr) ? def->m_replace : elem; } return ret; } -static pstring catremainder(const std::vector<pstring> &elems, std::size_t start, pstring sep) +static pstring catremainder(const std::vector<pstring> &elems, std::size_t start, const pstring &sep) { pstring ret(""); - for (auto & elem : elems) + for (std::size_t i = start; i < elems.size(); i++) { - ret += elem; + ret += elems[i]; ret += sep; } return ret; } -pstring ppreprocessor::process_line(const pstring &line) +pstring ppreprocessor::process_comments(pstring line) +{ + bool in_string = false; + + std::size_t e = line.size(); + pstring ret = ""; + for (std::size_t i=0; i < e; ) + { + pstring c = plib::left(line, 1); + line = line.substr(1); + if (!m_comment) + { + if (c=="\"") + { + in_string = !in_string; + ret += c; + } + else if (in_string && c=="\\") + { + i++; + ret += (c + plib::left(line, 1)); + line = line.substr(1); + } + else if (!in_string && c=="/" && plib::left(line,1) == "*") + m_comment = true; + else if (!in_string && c=="/" && plib::left(line,1) == "/") + break; + else + ret += c; + } + else + if (c=="*" && plib::left(line,1) == "/") + { + i++; + line = line.substr(1); + m_comment = false; + } + i++; + } + return ret; +} + +pstring ppreprocessor::process_line(pstring line) { - pstring lt = line.replace_all("\t"," ").trim(); + bool line_cont = plib::right(line, 1) == "\\"; + if (line_cont) + line = plib::left(line, line.size() - 1); + + if (m_state == LINE_CONTINUATION) + m_line += line; + else + m_line = line; + + if (line_cont) + { + m_state = LINE_CONTINUATION; + return ""; + } + else + m_state = PROCESS; + + line = process_comments(m_line); + + pstring lt = plib::trim(plib::replace_all(line, pstring("\t"), pstring(" "))); pstring ret; - m_lineno++; // FIXME ... revise and extend macro handling - if (lt.startsWith("#")) + if (plib::startsWith(lt, "#")) { std::vector<pstring> lti(psplit(lt, " ", true)); - if (lti[0].equals("#if")) + if (lti[0] == "#if") { m_level++; std::size_t start = 0; lt = replace_macros(lt); - std::vector<pstring> t(psplit(lt.substr(3).replace_all(" ",""), m_expr_sep)); - int val = static_cast<int>(expr(t, start, 0)); + std::vector<pstring> t(psplit(replace_all(lt.substr(3), pstring(" "), pstring("")), m_expr_sep)); + auto val = static_cast<int>(expr(t, start, 255)); if (val == 0) m_ifflag |= (1 << m_level); } - else if (lti[0].equals("#ifdef")) + else if (lti[0] == "#ifdef") { m_level++; if (get_define(lti[1]) == nullptr) m_ifflag |= (1 << m_level); } - else if (lti[0].equals("#ifndef")) + else if (lti[0] == "#ifndef") { m_level++; if (get_define(lti[1]) != nullptr) m_ifflag |= (1 << m_level); } - else if (lti[0].equals("#else")) + else if (lti[0] == "#else") { m_ifflag ^= (1 << m_level); } - else if (lti[0].equals("#endif")) + else if (lti[0] == "#endif") { m_ifflag &= ~(1 << m_level); m_level--; } - else if (lti[0].equals("#include")) + else if (lti[0] == "#include") { // ignore } - else if (lti[0].equals("#pragma")) + else if (lti[0] == "#pragma") { - if (m_ifflag == 0 && lti.size() > 3 && lti[1].equals("NETLIST")) + if (m_ifflag == 0 && lti.size() > 3 && lti[1] == "NETLIST") { - if (lti[2].equals("warning")) + if (lti[2] == "warning") error("NETLIST: " + catremainder(lti, 3, " ")); } } - else if (lti[0].equals("#define")) + else if (lti[0] == "#define") { if (m_ifflag == 0) { @@ -470,28 +514,20 @@ pstring ppreprocessor::process_line(const pstring &line) } } else - error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(line)); + { + if (m_ifflag == 0) + error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(replace_macros(line))); + } } else { lt = replace_macros(lt); if (m_ifflag == 0) - { ret += lt; - } } return ret; } -void ppreprocessor::process(putf8_reader &istrm, putf8_writer &ostrm) -{ - pstring line; - while (istrm.readline(line)) - { - line = process_line(line); - ostrm.writeline(line); - } -} -} +} // namespace plib |