this repo has no description
at fixPythonPipStalling 192 lines 4.8 kB view raw
1#include "RezLexer.h" 2 3#include <boost/wave.hpp> 4#include <boost/wave/cpplexer/cpp_lex_iterator.hpp> 5#include <boost/wave/token_ids.hpp> 6#include <boost/regex.hpp> 7 8#include "RezLexerWaveToken.h" 9#include "RezWorld.h" 10#include "Diagnostic.h" 11 12namespace wave = boost::wave; 13 14using namespace boost::wave; 15 16static std::string readContents(std::istream&& instream) 17{ 18 instream.unsetf(std::ios::skipws); 19 20 return std::string(std::istreambuf_iterator<char>(instream.rdbuf()), 21 std::istreambuf_iterator<char>()); 22} 23 24static std::string preFilter(std::string str) 25{ 26 boost::regex endif("#endif[^\r\n]*"); 27 str = boost::regex_replace(str, endif, "#endif"); 28 29 boost::regex dollar_escape("\\\\\\$([a-zA-Z0-9][a-zA-Z0-9])"); 30 str = boost::regex_replace(str, dollar_escape, "\\\\0x$1"); 31 32 if(str.size() == 0 || str[str.size()-1] != '\n') 33 str += "\n"; 34 return str; 35} 36 37struct load_file_to_string_filtered 38{ 39 template <typename IterContextT> 40 class inner 41 { 42 public: 43 template <typename PositionT> 44 static void init_iterators(IterContextT &iter_ctx, 45 PositionT const &act_pos, language_support language) 46 { 47 typedef typename IterContextT::iterator_type iterator_type; 48 49 // read in the file 50 std::ifstream instream(iter_ctx.filename.c_str()); 51 if (!instream.is_open()) { 52 BOOST_WAVE_THROW_CTX(iter_ctx.ctx, preprocess_exception, 53 bad_include_file, iter_ctx.filename.c_str(), act_pos); 54 return; 55 } 56 57 iter_ctx.instring = preFilter(readContents(std::move(instream))); 58 59 iter_ctx.first = iterator_type( 60 iter_ctx.instring.begin(), iter_ctx.instring.end(), 61 PositionT(iter_ctx.filename), language); 62 iter_ctx.last = iterator_type(); 63 } 64 65 private: 66 std::string instring; 67 }; 68}; 69 70 71 72typedef wave::cpplexer::lex_iterator< 73 wave::cpplexer::lex_token<> > 74 lex_iterator_type; 75typedef wave::context< 76 std::string::iterator, lex_iterator_type, 77 load_file_to_string_filtered> 78 context_type; 79typedef context_type::iterator_type pp_iterator_type; 80 81struct RezLexer::Priv 82{ 83 std::string input; 84 context_type ctx; 85 pp_iterator_type iter; 86 87 Priv(std::string data, std::string name) 88 : input(data), ctx(input.begin(), input.end(), name.c_str()) 89 { 90 } 91}; 92 93static std::string readInitial(RezWorld& world, std::string filename) 94{ 95 std::ifstream in(filename); 96 if(!in.is_open()) 97 { 98 world.problem(Diagnostic(Diagnostic::error, 99 "could not open " + filename, yy::location())); 100 } 101 return readContents(std::move(in)); 102} 103 104RezLexer::RezLexer(RezWorld& world, std::string filename) 105 : RezLexer(world, filename, readInitial(world,filename)) 106{ 107} 108 109 110 111RezLexer::RezLexer(RezWorld& world, std::string filename, const std::string &data) 112 : world(world), curFile(filename), lastLocation(&curFile) 113{ 114 pImpl.reset(new Priv(preFilter(data), filename)); 115 116 pImpl->ctx.add_macro_definition("DeRez=0"); 117 pImpl->ctx.add_macro_definition("Rez=1"); 118 pImpl->ctx.add_macro_definition("true=1"); 119 pImpl->ctx.add_macro_definition("false=0"); 120 pImpl->ctx.add_macro_definition("TRUE=1"); 121 pImpl->ctx.add_macro_definition("FALSE=0"); 122 123 pImpl->iter = pImpl->ctx.begin(); 124} 125 126RezLexer::~RezLexer() 127{ 128 129} 130 131 132 133void RezLexer::addDefine(std::string str) 134{ 135 pImpl->ctx.add_macro_definition(str); 136} 137 138void RezLexer::addIncludePath(std::string path) 139{ 140 std::size_t pos = path.find(':'); 141 if(pos == std::string::npos) 142 { 143 pImpl->ctx.add_include_path(path.c_str()); 144 } 145 else 146 { 147 addIncludePath(path.substr(0,pos)); 148 addIncludePath(path.substr(pos + 1)); 149 } 150} 151 152bool RezLexer::atEnd() 153{ 154 return pImpl->iter == pImpl->ctx.end(); 155} 156 157RezLexer::WaveToken RezLexer::nextWave() 158{ 159 try 160 { 161 if(pImpl->iter == pImpl->ctx.end()) 162 return WaveToken(); 163 else 164 { 165 WaveToken tok = *pImpl->iter++; 166 return tok; 167 } 168 } 169 catch(const preprocess_exception& e) 170 { 171 curFile = e.file_name(); 172 auto yypos = yy::position(&curFile, e.line_no(), e.column_no()); 173 yy::location loc(yypos); 174 lastLocation = loc; 175 176 world.problem(Diagnostic( 177 e.severity_level(e.get_errorcode()) >= util::severity_error 178 ? Diagnostic::error 179 : Diagnostic::warning, 180 preprocess_exception::error_text(e.get_errorcode()), loc)); 181 if(e.is_recoverable()) 182 return nextWave(); 183 else 184 return WaveToken(); 185 } 186} 187 188RezLexer::WaveToken RezLexer::peekWave() 189{ 190 return pImpl->iter == pImpl->ctx.end() ? WaveToken() : *pImpl->iter; 191} 192