Merge branch 'master' into 7.0.x
Fix conflicts with Apex CC category properties
This commit is contained in:
@ -96,7 +96,7 @@ public final class CppParser {
|
||||
if (t.kind != ID && t.kind != SCOPE)
|
||||
return null;
|
||||
|
||||
StringBuffer s = new StringBuffer();
|
||||
StringBuilder s = new StringBuilder();
|
||||
|
||||
int i;
|
||||
if (t.kind != SCOPE)
|
||||
@ -284,37 +284,100 @@ TOKEN :
|
||||
|
||||
TOKEN [IGNORE_CASE] :
|
||||
{
|
||||
< OCTALINT : "0" (["0"-"7"])* >
|
||||
< OCTALINT : "0" (["'", "0"-"7"])* >
|
||||
| < OCTALLONG : <OCTALINT> "l" >
|
||||
| < UNSIGNED_OCTALINT : <OCTALINT> "u" >
|
||||
| < UNSIGNED_OCTALLONG : <OCTALINT> ("ul" | "lu") >
|
||||
|
||||
| < DECIMALINT : ["1"-"9"] (["0"-"9"])* >
|
||||
| < #DECIMALDIGIT : ["'", "0"-"9"] >
|
||||
|
||||
| < DECIMALINT : ["1"-"9"] (<DECIMALDIGIT>)* >
|
||||
| < DECIMALLONG : <DECIMALINT> ["u","l"] >
|
||||
| < UNSIGNED_DECIMALINT : <DECIMALINT> "u" >
|
||||
| < UNSIGNED_DECIMALLONG : <DECIMALINT> ("ul" | "lu") >
|
||||
|
||||
|
||||
| < HEXADECIMALINT : "0x" (["0"-"9","a"-"f"])+ >
|
||||
| < HEXADECIMALINT : "0x" (<DECIMALDIGIT> | ["a"-"f"])+ >
|
||||
| < HEXADECIMALLONG : <HEXADECIMALINT> (["u","l"])? >
|
||||
| < UNSIGNED_HEXADECIMALINT : <HEXADECIMALINT> "u" >
|
||||
| < UNSIGNED_HEXADECIMALLONG : <HEXADECIMALINT> ("ul" | "lu") >
|
||||
|
||||
|
||||
| < FLOATONE : ((["0"-"9"])+ "." (["0"-"9"])* | (["0"-"9"])* "." (["0"-"9"])+)
|
||||
("e" (["-","+"])? (["0"-"9"])+)? (["f","l"])? >
|
||||
| < FLOATONE : (["0"-"9"](<DECIMALDIGIT>)* "."
|
||||
| "." (<DECIMALDIGIT>)+
|
||||
| ["0"-"9"](<DECIMALDIGIT>)* "." (<DECIMALDIGIT>)+)
|
||||
("e" (["-","+"])? (<DECIMALDIGIT>)+)? (["f","l"])? >
|
||||
|
||||
| < FLOATTWO : (["0"-"9"])+ "e" (["-","+"])? (["0"-"9"])+ (["f","l"])? >
|
||||
| < FLOATTWO : ["0"-"9"](<DECIMALDIGIT>)* "e" (["-","+"])? (<DECIMALDIGIT>)+ (["f","l"])? >
|
||||
}
|
||||
|
||||
TOKEN :
|
||||
{
|
||||
< #CHRPREF : <STRPREF>>
|
||||
| < CHARACTER : <CHRPREF>
|
||||
"'" ( ( ~["'","\\","\r","\n"] ) | ( "\\" ( ~["\n","\r"] ) ) )* "'" >
|
||||
|
||||
< CHARACTER : ("L")? "'" ( ( ~["'","\\","\r","\n"] ) | ( "\\" ( ~["\n","\r"] ) ) )* "'" >
|
||||
| < #STRPREF : ("L" | "u" | "U" | "u8")? >
|
||||
| < STRING : <STRPREF>
|
||||
"\"" ( ( ~["\"","\\","\r","\n"] ) | ( "\\" ( ~["\n","\r"] | "\n" | "\r\n" ) ) )* "\"" >
|
||||
|
||||
| < STRING : ("L")? "\"" ( ( ~["\"","\\","\r","\n"] ) | ( "\\" ( ~["\n","\r"] | "\n" | "\r\n" ) ) )* "\"" >
|
||||
}
|
||||
|
||||
| < RSTRING : "R\"(" ( ~[")"] | ( ")" ~["\""] ) )* ")\"" >
|
||||
// Raw C++11 string literal support
|
||||
// https://en.cppreference.com/w/cpp/language/string_literal
|
||||
TOKEN :
|
||||
{
|
||||
< RSTRING : <STRPREF> "R\"" >
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(16);
|
||||
|
||||
// delim ------+
|
||||
// vvv
|
||||
// Matching R"...(...)..."
|
||||
// ^
|
||||
for (;;) {
|
||||
try { curChar = input_stream.readChar(); }
|
||||
catch(java.io.IOException e) { return; }
|
||||
if (curChar == '(') break;
|
||||
sb.append(curChar);
|
||||
}
|
||||
final String delim = sb.toString();
|
||||
|
||||
rstringbody:
|
||||
// Matching R"...(...)..."
|
||||
// ^
|
||||
for (;;) {
|
||||
try { curChar = input_stream.readChar(); }
|
||||
catch(java.io.IOException e) { return; }
|
||||
if (curChar == ')') {
|
||||
// delim --------------+
|
||||
// vvv
|
||||
// Matching R"...(...)..."
|
||||
// ^^^
|
||||
for (int i = 0; i < delim.length(); i++) {
|
||||
try { curChar = input_stream.readChar(); }
|
||||
catch(java.io.IOException e) { return; }
|
||||
if (delim.charAt(i) != curChar) {
|
||||
input_stream.backup(1);
|
||||
continue rstringbody;
|
||||
}
|
||||
}
|
||||
// Matching R"...(...)..."
|
||||
// ^
|
||||
try { curChar = input_stream.readChar(); }
|
||||
catch(java.io.IOException e) { return; }
|
||||
if (curChar != '"') {
|
||||
input_stream.backup(1);
|
||||
continue rstringbody;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Setting final token image
|
||||
matchedToken.image = input_stream.GetImage();
|
||||
matchedToken.endLine = input_stream.getEndLine();
|
||||
matchedToken.endColumn = input_stream.getEndColumn();
|
||||
}
|
||||
}
|
||||
|
||||
TOKEN :
|
||||
|
@ -159,6 +159,86 @@ public class CPPTokenizerTest {
|
||||
tokenizer.tokenize(code, new Tokens());
|
||||
}
|
||||
|
||||
public void testStringPrefix(String code, String expToken, int tokenIndex, int expNoTokens) {
|
||||
final Tokens tokens = parse(code);
|
||||
final TokenEntry token = tokens.getTokens().get(tokenIndex);
|
||||
assertEquals(expNoTokens, tokens.size());
|
||||
assertEquals(expToken, token.toString());
|
||||
}
|
||||
|
||||
public void testCharacterPrefix(String code, String expToken) {
|
||||
testStringPrefix(code, expToken, 3, 6);
|
||||
}
|
||||
|
||||
public void testStringPrefix(String code, String expToken) {
|
||||
testStringPrefix(code, expToken, 5, 8);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharacterPrefixNoPrefix() {
|
||||
testCharacterPrefix("char a = '\\x30';", "'\\x30'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharacterPrefixWideCharacter() {
|
||||
testCharacterPrefix("wchar_t b = L'\\xFFEF';", "L'\\xFFEF'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharacterPrefixChar16() {
|
||||
testCharacterPrefix("char16_t c = u'\\u00F6';", "u'\\u00F6'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharacterPrefixChar32() {
|
||||
testCharacterPrefix("char32_t d = U'\\U0010FFFF';", "U'\\U0010FFFF'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringPrefixNoPrefix() {
|
||||
testStringPrefix("char A[] = \"Hello\\x0A\";", "\"Hello\\x0A\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringPrefixWideString() {
|
||||
testStringPrefix("wchar_t B[] = L\"Hell\\xF6\\x0A\";", "L\"Hell\\xF6\\x0A\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringPrefixChar16() {
|
||||
testStringPrefix("char16_t C[] = u\"Hell\\u00F6\";", "u\"Hell\\u00F6\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringPrefixChar32() {
|
||||
testStringPrefix("char32_t D[] = U\"Hell\\U000000F6\\U0010FFFF\";", "U\"Hell\\U000000F6\\U0010FFFF\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringPrefixUtf8() {
|
||||
testStringPrefix("auto E[] = u8\"\\u00F6\\U0010FFFF\";", "u8\"\\u00F6\\U0010FFFF\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRawStringLiterals() throws IOException {
|
||||
final String code = IOUtils.toString(CPPTokenizerTest.class.getResourceAsStream("cpp/issue-1784.cpp"), StandardCharsets.UTF_8);
|
||||
Tokens tokens = parse(code);
|
||||
assertTrue(TokenEntry.getEOF() != tokens.getTokens().get(0));
|
||||
assertEquals(16, tokens.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDigitSeparators() {
|
||||
final String code = "auto integer_literal = 1'000'000;" + PMD.EOL
|
||||
+ "auto floating_point_literal = 0.000'015'3;" + PMD.EOL
|
||||
+ "auto hex_literal = 0x0F00'abcd'6f3d;" + PMD.EOL
|
||||
+ "auto silly_example = 1'0'0'000'00;";
|
||||
Tokens tokens = parse(code);
|
||||
assertTrue(TokenEntry.getEOF() != tokens.getTokens().get(0));
|
||||
assertEquals("1'000'000", tokens.getTokens().get(3).toString());
|
||||
assertEquals(21, tokens.size());
|
||||
}
|
||||
|
||||
private Tokens parse(String snippet) {
|
||||
try {
|
||||
return parse(snippet, false, new Tokens());
|
||||
|
@ -4,7 +4,7 @@ namespace ABC
|
||||
{
|
||||
|
||||
#ifdef USE_QT
|
||||
const char* perPixelQml = R"QML(
|
||||
const char* perPixelQml = "QML( // provoking a parser error
|
||||
)QML";
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
namespace ABC
|
||||
{
|
||||
namespace DEF
|
||||
{
|
||||
|
||||
#ifdef USE_QT
|
||||
const char* perPixelQml = R"QML(
|
||||
)NOTTHEND";
|
||||
)QML";
|
||||
}
|
||||
}
|
||||
#endif // USE_QT
|
Reference in New Issue
Block a user