How to exclude C++ raw string literals from syntax highlighting in Vim? - c++

Quite honestly, raw string literals are a great addition to the C++ language. But (as expected) editors have a hard time to properly display those literals.
I am using Vim 7.4 and out-of-the-box raw string literals completely break the syntax highlighting. For example in
char const txt[] = R"(printf(")";
the 2nd '(' is highlighted red in vim.
Something like
char const txt2[] = R"( "{{" )";
breaks the highlighting of curly braces and the syntax based auto-ident - and so on.
For a start I would be happy to have Vim ignore everything between R"( and )" when doing syntax highlighting.
But note that raw string literals are flexible - arbitrary matching strings are allowed between the first/last double-quote/brace pair, e.g.
R"abcd()")")abcd"
is also a valid raw string literal which encodes
)")"
See also the cppreference link for a general definition of the syntax.
Thus my question how to configure Vim such that C++ raw string literals are properly recognized.
Vim already seems to include some facilities to properly synatx highlight language fragments embedded in a host language (e.g. for compiler-compiler source files). Perhaps they can be used for the raw string literal case as well?

Add this
syntax match cString 'R"\([^(]*\)(\_.*)\1"'
to your custom C++ syntax file (normally ~/.vim/syntax/cpp.vim ; create this file if you don't have one).

Just add cpp-vim as a plugin. I have added strict support for newer string literals in pull-request #14.
This is what you get: http://bl.ocks.org/anonymous/raw/9442865
cpp-vim adds support for other C++11 stuff too.

A tiny tweak on the above syntax rule:
syntax match cString 'R"\([^(]*\)(\_.\{-})\1"'
The original attempts to greedily select the longest match; so if you have multiple raw strings in a file (using the same open/close pattern) is would break.
This one is non-greedy, and should match correctly.
Thank you so much for the original though, it was a huge help to me!

Related

c++, How to disable escape sequence in visual studio 2019? [duplicate]

For regular expression \w+\d, in many script language such as perl/python it can be written literally. But in C/C++, I must write it as:
const char *re_str = "\\w+\\d";
which is ugly to eye.
Is there any method to avoid it? MACRO are also acceptable.
Just as an FYI, the next C++ standard (C++ 0x) will have something called raw string literals which should let you do something like:
const char *re_str = R"(\w+\d)";
However until then I think you're stuck with the pain of doubling up your backslashes if you want the regex to be a literal in the source file.
When I reading [C: A reference manual] Chapter 3: Prepressors. An idea emerges:
#define STR(a) #a
#define R(var, re) static char var##_[] = STR(re);\
const char * var = ( var##_[ sizeof(var##_) - 2] = '\0', (var##_ + 1) );
R(re, "\w\d");
printf("Hello, world[%s]\n", re);
It's portable in both C and C++, only uses standard preprocessing features. The trick is to use macro to expand \ inside liternal string and then remove the leading and tailing double quote strings.
Now I think it's the best way until C++0x really introduce the new literal string syntax R"...". And for C I think it'll be the best way for a long time.
The side effect is that we cannot defined such a variable in the global scope in C. Because there's a statement to remove the tailing double-quote character. In C++ it's OK.
You can put your regexp in a file and read the file if you have a lot or need to modify them often. That's the only way I see to avoid backslashes.
No. There is only one kind of string literals in C++, and it's the kind that treats escaped characters.

Regex For Strings in C

I'm looking to make a regular expression for some strings in C.
This is what i have so far:
Strings in C are delimited by double quotes (") so the regex has to be surrounded by \" \".
The string may not contain newline characters so I need to do [^\n] ( I think ).
The string may also contain double quotes or back slash characters if and only if they're escaped. Therefore [\\ \"] (again I think).
Other than that anything else goes.
Any help is much appreciated I'm kind of lost on how to start writing this regex.
A simple flex pattern to recognize string literals (including literals with embedded line continuations):
["]([^"\\\n]|\\.|\\\n)*["]
That will allow
"string with \
line continuation"
But not
"C doesn't support
multiline strings"
If you don't want to deal with line continuations, remove the \\\n alternative. If you need trigraph support, it gets more irritating.
Although that recognizes strings, it doesn't attempt to make sense of them. Normally, a C lexer will want to process strings with backslash sequences, so that "\"\n" is converted to the two characters "NL (0x22 0x0A). You might, at some point, want to take a look at, for example, Optimizing flex string literal parsing (although that will need to be adapted if you are programming in C).
Flex patterns are documented in the flex manual. It might also be worthwhile reading a good reference on regular expressions, such as John Levine's excellent book on Flex and Bison.

Regexp languages and replacements in Emacs

When I use the regexp-builder, I need to escape things in a different way from the way I do it when using replace-regexp. Now, this thread explains that these two commands use a different syntax, but why is that?
Also, I went through this blog post: Re-builder: The Interactive Regexp Builder, and I added
(require 're-builder)
(setq reb-re-syntax 'string)
to my .emacs file following the advice on the site. However, I still need to type " around my regexp to make it work. I thought changing the syntax language would take care of this but it doesn't.
With this, my actual questions are:
Is it sill the case that Emacs does not support PCRE? Are there any workarounds to this?
Once I have the right regexp in regex-builder, is there any way to directly send the regexp to replace-regexp and enter the replacement string?
There's a package in the MELPA repository called pcre2el that adds PCRE support to many parts of Emacs, including regexp-builder and replace-regexp.
Regarding question #2: No (at least not by default), but there's another way to do that without using re-builder.
Start by doing a regexp isearch for your pattern. Because it's an isearch, you'll see the matches interactively, a bit like re-builder (albeit without coloured groupings).
Still in isearch, once you're happy with the pattern, type C-M-% to call isearch-query-replace-regexp which will prompt you for the replacement.
You can of course simply copy your re-builder string from its buffer and yank it as a replacement string (but that's undoubtedly not news).
I was curious about the need for quotes in re-builder with string syntax. It seems that's it's just a formality of the system, and reb-read-regexp returns everything between the first and last " when using that syntax. Maybe it's intended to ensure that leading or trailing whitespace can't confuse matters -- re-builder does use leading whitespace for improved visibility, and trailing whitespace would be harder to spot. Or maybe it just made some of the code more convenient/consistent.
No, Emacs doesn't support PCRE, and as far as I know there is no work-around for that.
I don't think so.
To answer your first question, why does re-builder use a different syntax than replace-regexp:
By default, re-builder uses the syntax that is appropriate for writing elisp programs. In the context of a written program, regexps are entered within strings. Inside a string, backslashes have a special meaning which conflicts with using the backslash as part of a regexp. Consequently, within a string, you need to double a backslash to use it to signify part of the regexp syntax.
replace-regexp, on the other hand, is designed to be used interactively by the user, and it explicitly expects the input to be a regexp. As a convenience, it interprets backslashes as regexp syntax, not as string escapes. Which is why you can use single backslashes in this context.

Why must C/C++ string literal declarations be single-line?

Is there any particular reason that multi-line string literals such as the following are not permitted in C++?
string script =
"
Some
Formatted
String Literal
";
I know that multi-line string literals may be created by putting a backslash before each newline.
I am writing a programming language (similar to C) and would like to allow the easy creation of multi-line strings (as in the above example).
Is there any technical reason for avoiding this kind of string literal? Otherwise I would have to use a python-like string literal with a triple quote (which I don't want to do):
string script =
"""
Some
Formatted
String Literal
""";
Why must C/C++ string literal declarations be single-line?
The terse answer is "because the grammar prohibits multiline string literals." I don't know whether there is a good reason for this other than historical reasons.
There are, of course, ways around this. You can use line splicing:
const char* script = "\
Some\n\
Formatted\n\
String Literal\n\
";
If the \ appears as the last character on the line, the newline will be removed during preprocessing.
Or, you can use string literal concatenation:
const char* script =
" Some\n"
" Formatted\n"
" String Literal\n";
Adjacent string literals are concatenated during preprocessing, so these will end up as a single string literal at compile-time.
Using either technique, the string literal ends up as if it were written:
const char* script = " Some\n Formatted\n String Literal\n";
One has to consider that C was not written to be an "Applications" programming language but a systems programming language. It would not be inaccurate to say it was designed expressly to rewrite Unix. With that in mind, there was no EMACS or VIM and your user interfaces were serial terminals. Multiline string declarations would seem a bit pointless on a system that did not have a multiline text editor. Furthermore, string manipulation would not be a primary concern for someone looking to write an OS at that particular point in time. The traditional set of UNIX scripting tools such as AWK and SED (amongst MANY others) are a testament to the fact they weren't using C to do significant string manipulation.
Additional considerations: it was not uncommon in the early 70s (when C was written) to submit your programs on PUNCH CARDS and come back the next day to get them. Would it have eaten up extra processing time to compile a program with multiline strings literals? Not really. It can actually be less work for the compiler. But you were going to come back for it the next day anyhow in most cases. But nobody who was filling out a punch card was going to put large amounts of text that wasn't needed in their programs.
In a modern environment, there is probably no reason not to include multiline string literals other than designer's preference. Grammatically speaking, it's probably simpler because you don't have to take linefeeds into consideration when parsing the string literal.
In addition to the existing answers, you can work around this using C++11's raw string literals, e.g.:
#include <iostream>
#include <string>
int main() {
std::string str = R"(a
b)";
std::cout << str;
}
/* Output:
a
b
*/
Live demo.
[n3290: 2.14.5/4]: [ Note: A source-file new-line in a raw string
literal results in a new-line in the resulting execution
string-literal. Assuming no whitespace at the beginning of lines in
the following example, the assert will succeed:
const char *p = R"(a\
b
c)";
assert(std::strcmp(p, "a\\\nb\nc") == 0);
—end note ]
Though non-normative, this note and the example that follows it in [n3290: 2.14.5/5] serve to complement the indication in the grammar that the production r-char-sequence may contain newlines (whereas the production s-char-sequence, used for normal string literals, may not).
Others have mentioned some excellent workarounds, I just wanted to address the reason.
The reason is simply that C was created at a time when processing was at a premium and compilers had to be simple and as fast as possible. These days, if C were to be updated (I'm looking at you, C1X), it's quite possible to do exactly what you want. It's unlikely, however. Mostly for historical reasons; such a change could require extensive rewrites of compilers, and so will likely be rejected.
The C preprocessor works on a line-by-line basis, but with lexical tokens. That means that the preprocessor understands that "foo" is a token. If C were to allow multi-line literals, however, the preprocessor would be in trouble. Consider:
"foo
#ifdef BAR
bar
#endif
baz"
The preprocessor isn't able to mess with the inside of a token - but it's operating line-by-line. So how is it supposed to handle this case? The easy solution is to simply forbid multiline strings entirely.
Actually, you can break it up thus:
string script =
"\n"
" Some\n"
" Formatted\n"
" String Literal\n";
Adjacent string literals are concatenated by the compiler.
Strings can lay on multiple lines, but each line has to be quoted individually :
string script =
" \n"
" Some \n"
" Formatted \n"
" String Literal ";
I am writing a programming language
(similar to C) and would like to let
write multi-line strings easily (like
in above example).
There is no reason why you couldn't create a programming language that allows multi-line strings.
For example, Vedit Macro Language (which is C-like scripting language for VEDIT text editor) allows multi-line strings, for example:
Reg_Set(1,"
Some
Formatted
String Literal
")
It is up to you how you define your language syntax.
You can also do:
string useMultiple = "this"
"is "
"a string in C.";
Place one literal after another without any special chars.
Literal declarations doesn't have to be single-line.
GPUImage inlines multiline shader code. Checkout its SHADER_STRING macro.

Is the syntax for writing regular expression standardized

Is the syntax for writing regular expression standardized? That is, if I write a regular expression in C++ it will work in Python or Javascript without any modifications.
No, there are several dialects of Regular Expressions.
They generally have many elements in common.
Some popular ones are listed and compared here.
Simple regular expressions, mostly yes. However, across the spectrum of programming languages, there are differences.
No, here are some differences that comes to mind:
JavaScript lets you write inline regex (where \ in \s need not be escaped as \\s), that are delimited by the / character. You can specify flags after the closing /. JS also has RegExp constructor that takes the escaped string as the first argument and an optional flag string as second argument.
/^\w+$/i and new RegExp("^\\w+$", "i") are valid and the same.
In PHP, you can enclose the regex string inside an arbitrary delimiter of your choice (not sure of the super set of characters that can be used as delimiters though). Again you should escape backslashes here.
"|[0-9]+|" is same as #[0-9]+#
Python and C# supports raw strings (not limited to regex, but really helpful for writing regex) that lets you write unescaped backslashes in your regex.
"\\d+\\s+\\w+" can be written as r'\d+\s+\w+' in Python and #'\d+\s+\w+' in C#
Delimiters like \<, \A etc are not globally supported.
JavaScript doesn't support lookbehind and the DOTALL flag.