cppparser: support C++11 raw string literals

This commit is contained in:
rdb 2017-01-14 22:35:38 +01:00
parent a15d84dbeb
commit 5aabd56697
3 changed files with 53 additions and 5 deletions

View File

@ -1558,6 +1558,10 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
out << "\\\"";
break;
case '\\':
out << "\\\\";
break;
default:
if (isprint(*si)) {
out << *si;

View File

@ -1870,11 +1870,19 @@ get_identifier(int c) {
loc.last_column = get_col_number();
if ((c == '\'' || c == '"') &&
(name == "L" || name == "u8" ||
name == "u" || name == "U")) {
(name == "L" || name == "u8" || name == "u" || name == "U" ||
name == "R" || name == "LR" || name == "u8R" || name == "uR" || name == "UR")) {
// This is actually a wide-character or wide-string literal or some such.
// Figure out the correct character type to use.
get();
string str;
if (name[name.size() - 1] == 'R') {
name.resize(name.size() - 1);
str = scan_raw(c);
} else {
str = scan_quoted(c);
}
// Figure out the correct character type to use.
CPPExpression::Type type;
if (name == "L") {
type = CPPExpression::T_wstring;
@ -1887,8 +1895,6 @@ get_identifier(int c) {
} else {
type = CPPExpression::T_string;
}
get();
string str = scan_quoted(c);
loc.last_line = get_line_number();
loc.last_column = get_col_number();
@ -2772,6 +2778,43 @@ scan_quoted(int c) {
return str;
}
/**
* Parses a C++11 raw string.
*/
string CPPPreprocessor::
scan_raw(int c) {
int quote_mark = c;
string delimiter = ")";
string str;
c = get();
while (c != EOF && c != '(') {
delimiter += c;
c = get();
}
// OK, now start parsing the string, until we see the delimiter again.
c = get();
while (c != EOF) {
if (c == quote_mark) {
// We encountered a quote mark - did the last part of the string end
// with the given delimiter? If so, we've reached the end.
if (str.compare(str.size() - delimiter.size(), delimiter.size(), delimiter) == 0) {
str.resize(str.size() - delimiter.size());
break;
}
}
str += c;
c = get();
}
if (c != quote_mark) {
warning("Unclosed string");
}
return str;
}
/**
* Returns true if the manifest is one that is being ignored right now
* (presumably because we are presently expanding it).

View File

@ -166,6 +166,7 @@ private:
static int check_keyword(const string &name);
int scan_escape_sequence(int c);
string scan_quoted(int c);
string scan_raw(int c);
bool should_ignore_manifest(const CPPManifest *manifest) const;
bool should_ignore_preprocessor() const;