// See the file "COPYING" in the main distribution directory for copyright. #include "pac_regex.h" #include "pac_exttype.h" #include "pac_id.h" #include "pac_output.h" #include "pac_type.h" // Depends on the regular expression library we are using const char* RegEx::kREMatcherType = "RegExMatcher"; const char* RegEx::kMatchPrefix = "MatchPrefix"; string escape_char(const string& s) { char* buf = new char[s.length() * 2 + 1]; int j = 0; for ( int i = 0; i < (int)s.length(); ++i ) { if ( s[i] == '\\' ) { if ( i + 1 < (int)s.length() ) { buf[j++] = '\\'; if ( s[i + 1] == '/' ) buf[j - 1] = s[++i]; else if ( s[i + 1] == '/' || s[i + 1] == '\\' || s[i + 1] == '"' ) buf[j++] = s[++i]; else buf[j++] = '\\'; } } else if ( s[i] == '"' ) { buf[j++] = '\\'; buf[j++] = '"'; } else { buf[j++] = s[i]; } } buf[j++] = '\0'; string rval = buf; delete[] buf; return rval; } RegEx::RegEx(const string& s) { str_ = escape_char(s); string prefix = strfmt("%s_re_", current_decl_id->Name()); matcher_id_ = ID::NewAnonymousID(prefix); decl_ = new RegExDecl(this); } RegEx::~RegEx() {} RegExDecl::RegExDecl(RegEx* regex) : Decl(regex->matcher_id(), REGEX) { regex_ = regex; } void RegExDecl::Prepare() { global_env()->AddID(id(), GLOBAL_VAR, extern_type_re_matcher); } void RegExDecl::GenForwardDeclaration(Output* out_h) { out_h->println("extern %s %s;\n", RegEx::kREMatcherType, global_env()->LValue(regex_->matcher_id())); } void RegExDecl::GenCode(Output* out_h, Output* out_cc) { out_cc->println("%s %s(\"%s\");\n", RegEx::kREMatcherType, global_env()->LValue(regex_->matcher_id()), regex_->str().c_str()); }