C++: Implement POSIX collating symbols

This commit is contained in:
copilot-swe-agent[bot]
2026-07-23 10:22:15 +00:00
committed by GitHub
parent ea561e2994
commit afde8d9fc5
4 changed files with 80 additions and 63 deletions

View File

@@ -49,7 +49,11 @@ private newtype TRegExpParent =
not re.specialCharacter(start, end, _)
} or
/** A back reference */
TRegExpBackRef(RegExp re, int start, int end) { re.backreference(start, end) }
TRegExpBackRef(RegExp re, int start, int end) { re.backreference(start, end) } or
/** A POSIX collating symbol */
TRegExpPosixCollatingSymbol(RegExp re, int start, int end) {
re.posixStyleCollatingSymbol(start, end, _)
}
/** An implementation that satisfies the RegexTreeView signature. */
private module Impl implements RegexTreeViewSig {
@@ -137,6 +141,8 @@ private module Impl implements RegexTreeViewSig {
exists(seqChild(re, start, end, 1)) // if a sequence does not have more than one element, it should be treated as that element instead.
or
this = TRegExpSpecialChar(re, start, end)
or
this = TRegExpPosixCollatingSymbol(re, start, end)
}
/**
@@ -177,6 +183,8 @@ private module Impl implements RegexTreeViewSig {
result = this.(RegExpSequence).getChild(i)
or
result = this.(RegExpSpecialChar).getChild(i)
or
result = this.(RegExpPosixCollatingSymbol).getChild(i)
}
/**
@@ -1113,6 +1121,16 @@ private module Impl implements RegexTreeViewSig {
override predicate isNullable() { this.getGroup().isNullable() }
}
additional class RegExpPosixCollatingSymbol extends RegExpTerm, TRegExpPosixCollatingSymbol {
RegExpPosixCollatingSymbol() { this = TRegExpPosixCollatingSymbol(re, start, end) }
override RegExpTerm getChild(int i) { none() }
override string getAPrimaryQlClass() { result = "RegExpPosixCollatingSymbol" }
string getName() { re.posixStyleCollatingSymbol(start, end, result) }
}
class Top = RegExpParent;
/**

View File

@@ -101,7 +101,13 @@ abstract class RegExp extends StringLiteral {
// Brackets that art part of POSIX expressions should not count as
// char-set delimiters.
not exists(int x, int y |
this.posixStyleNamedCharacterProperty(x, y, _) and pos >= x and pos < y
(
this.posixStyleNamedCharacterProperty(x, y, _)
or
this.posixStyleCollatingSymbol(x, y, _)
) and
pos >= x and
pos < y
)
) and
(
@@ -133,7 +139,13 @@ abstract class RegExp extends StringLiteral {
e > innerStart and
this.nonEscapedCharAt(e) = "]" and
not exists(int x, int y |
this.posixStyleNamedCharacterProperty(x, y, _) and e >= x and e < y
(
this.posixStyleNamedCharacterProperty(x, y, _)
or
this.posixStyleCollatingSymbol(x, y, _)
) and
e >= x and
e < y
)
|
e
@@ -162,6 +174,8 @@ abstract class RegExp extends StringLiteral {
or
this.namedCharacterProperty(start, end, _)
or
this.posixStyleCollatingSymbol(start, end, _)
or
exists(this.nonEscapedCharAt(start)) and end = start + 1
)
or
@@ -171,6 +185,8 @@ abstract class RegExp extends StringLiteral {
or
this.namedCharacterProperty(start, end, _)
or
this.posixStyleCollatingSymbol(start, end, _)
or
exists(this.nonEscapedCharAt(start)) and
end = start + 1 and
not this.getChar(start) = "]"
@@ -313,6 +329,21 @@ abstract class RegExp extends StringLiteral {
)
}
/** Matches a POSIX collating symbol such as `[.ch.]` within a character class. */
predicate posixStyleCollatingSymbol(int start, int end, string name) {
this.getChar(start) = "[" and
this.getChar(start + 1) = "." and
end =
min(int e |
e > start and
this.getChar(e - 2) = "." and
this.getChar(e - 1) = "]"
|
e
) and
name = this.getText().substring(start + 2, end - 2)
}
/**
* Holds if the named character property is inverted. Examples for which it holds:
* - `\P{Digit}` upper-case P means inverted
@@ -371,7 +402,12 @@ abstract class RegExp extends StringLiteral {
*/
predicate inPosixBracket(int index) {
exists(int x, int y |
this.posixStyleNamedCharacterProperty(x, y, _) and index in [x + 1 .. y - 2]
(
this.posixStyleNamedCharacterProperty(x, y, _)
or
this.posixStyleCollatingSymbol(x, y, _)
) and
index in [x + 1 .. y - 2]
)
}
@@ -383,7 +419,11 @@ abstract class RegExp extends StringLiteral {
not this.charSet(start, _) and
not this.charSet(_, start + 1) and
not exists(int x, int y |
this.posixStyleNamedCharacterProperty(x, y, _) and
(
this.posixStyleNamedCharacterProperty(x, y, _)
or
this.posixStyleCollatingSymbol(x, y, _)
) and
start >= x and
end <= y
) and

View File

@@ -42,25 +42,7 @@
#-----| [RegExpConstant, RegExpNormalChar] [
#-----| [RegExpConstant, RegExpNormalChar] [
#-----| [RegExpConstant, RegExpNormalChar] .
#-----| [RegExpConstant, RegExpNormalChar] b
#-----| [RegExpConstant, RegExpNormalChar] .
#-----| [RegExpConstant, RegExpNormalChar] ]a-f]
#-----| [RegExpConstant, RegExpNormalChar] [
#-----| [RegExpConstant, RegExpNormalChar] .
#-----| [RegExpConstant, RegExpNormalChar] a
#-----| [RegExpConstant, RegExpNormalChar] .
#-----| [RegExpConstant, RegExpNormalChar] ]
#-----| [RegExpConstant, RegExpNormalChar] a-f]
#-----| [RegExpConstant, RegExpNormalChar] A
@@ -198,12 +180,8 @@
#-----| 2 -> [RegExpConstant, RegExpNormalChar] b
#-----| [RegExpSequence] [A-F[[.b.]]a-f]
#-----| 0 -> [RegExpCharacterClass] [A-F[[.b.]
#-----| 1 -> [RegExpConstant, RegExpNormalChar] ]a-f]
#-----| [RegExpSequence] [[.a.]]
#-----| 0 -> [RegExpCharacterClass] [[.a.]
#-----| 1 -> [RegExpConstant, RegExpNormalChar] ]
#-----| 0 -> [RegExpCharacterClass] [A-F[[.b.]]
#-----| 1 -> [RegExpConstant, RegExpNormalChar] a-f]
#-----| [RegExpSequence] [[:alpha:]][[:digit:]]
#-----| 0 -> [RegExpCharacterClass] [[:alpha:]]
@@ -268,6 +246,10 @@
#-----| 2 -> [RegExpOpt] c?
#-----| 3 -> [RegExpConstant, RegExpNormalChar] d
#-----| [RegExpPosixCollatingSymbol] [.b.]
#-----| [RegExpPosixCollatingSymbol] [.a.]
#-----| [RegExpBackRef] \1
#-----| [RegExpSpecialChar] \b
@@ -331,19 +313,13 @@
#-----| [RegExpCharacterClass] [\cZ]
#-----| 0 -> [RegExpConstant, RegExpEscape] \cZ
#-----| [RegExpCharacterClass] [A-F[[.b.]
#-----| [RegExpCharacterClass] [A-F[[.b.]]
#-----| 0 -> [RegExpCharacterRange] A-F
#-----| 1 -> [RegExpConstant, RegExpNormalChar] [
#-----| 2 -> [RegExpConstant, RegExpNormalChar] [
#-----| 3 -> [RegExpConstant, RegExpNormalChar] .
#-----| 4 -> [RegExpConstant, RegExpNormalChar] b
#-----| 5 -> [RegExpConstant, RegExpNormalChar] .
#-----| 2 -> [RegExpPosixCollatingSymbol] [.b.]
#-----| [RegExpCharacterClass] [[.a.]
#-----| 0 -> [RegExpConstant, RegExpNormalChar] [
#-----| 1 -> [RegExpConstant, RegExpNormalChar] .
#-----| 2 -> [RegExpConstant, RegExpNormalChar] a
#-----| 3 -> [RegExpConstant, RegExpNormalChar] .
#-----| [RegExpCharacterClass] [[.a.]]
#-----| 0 -> [RegExpPosixCollatingSymbol] [.a.]
#-----| [RegExpCharacterClass] [A-F[:digit:]a-f]
#-----| 0 -> [RegExpCharacterRange] A-F

View File

@@ -23,10 +23,6 @@ term
| file://:0:0:0:0 | (foo)*bar | RegExpSequence |
| file://:0:0:0:0 | (o\|b) | RegExpGroup |
| file://:0:0:0:0 | - | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | . | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | . | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | . | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | . | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | . | RegExpDot |
| file://:0:0:0:0 | . | RegExpDot |
| file://:0:0:0:0 | .* | RegExpStar |
@@ -48,14 +44,13 @@ term
| file://:0:0:0:0 | Z | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | [ | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | [ | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | [ | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | [ | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | [123] | RegExpCharacterClass |
| file://:0:0:0:0 | [.a.] | RegExpPosixCollatingSymbol |
| file://:0:0:0:0 | [.b.] | RegExpPosixCollatingSymbol |
| file://:0:0:0:0 | [A-F[:digit:]a-f] | RegExpCharacterClass |
| file://:0:0:0:0 | [A-F[[.b.] | RegExpCharacterClass |
| file://:0:0:0:0 | [A-F[[.b.]] | RegExpCharacterClass |
| file://:0:0:0:0 | [A-F[[.b.]]a-f] | RegExpSequence |
| file://:0:0:0:0 | [[.a.] | RegExpCharacterClass |
| file://:0:0:0:0 | [[.a.]] | RegExpSequence |
| file://:0:0:0:0 | [[.a.]] | RegExpCharacterClass |
| file://:0:0:0:0 | [[:alpha:][:digit:]] | RegExpCharacterClass |
| file://:0:0:0:0 | [[:alpha:]] | RegExpCharacterClass |
| file://:0:0:0:0 | [[:alpha:]][[:digit:]] | RegExpSequence |
@@ -105,8 +100,6 @@ term
| file://:0:0:0:0 | \| | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | ] | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | ] | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | ] | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | ]a-f] | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | _ | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | a | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | a | RegExpConstant,RegExpNormalChar |
@@ -120,13 +113,13 @@ term
| file://:0:0:0:0 | a | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | a | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | a | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | a | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | a* | RegExpStar |
| file://:0:0:0:0 | a*b+c?d | RegExpSequence |
| file://:0:0:0:0 | a+ | RegExpPlus |
| file://:0:0:0:0 | a-f | RegExpCharacterRange |
| file://:0:0:0:0 | a-f | RegExpCharacterRange |
| file://:0:0:0:0 | a-f | RegExpCharacterRange |
| file://:0:0:0:0 | a-f] | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | a\\nb | RegExpSequence |
| file://:0:0:0:0 | a\|b\|cd | RegExpAlt |
| file://:0:0:0:0 | abc | RegExpConstant,RegExpNormalChar |
@@ -152,7 +145,6 @@ term
| file://:0:0:0:0 | b | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | b | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | b | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | b | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | b+ | RegExpPlus |
| file://:0:0:0:0 | b+ | RegExpPlus |
| file://:0:0:0:0 | bar | RegExpConstant,RegExpNormalChar |
@@ -181,10 +173,6 @@ regExpNormalCharValue
| file://:0:0:0:0 | 9 | 9 |
| file://:0:0:0:0 | !a | !a |
| file://:0:0:0:0 | - | - |
| file://:0:0:0:0 | . | . |
| file://:0:0:0:0 | . | . |
| file://:0:0:0:0 | . | . |
| file://:0:0:0:0 | . | . |
| file://:0:0:0:0 | : | : |
| file://:0:0:0:0 | A | A |
| file://:0:0:0:0 | A | A |
@@ -197,8 +185,6 @@ regExpNormalCharValue
| file://:0:0:0:0 | Z | Z |
| file://:0:0:0:0 | [ | [ |
| file://:0:0:0:0 | [ | [ |
| file://:0:0:0:0 | [ | [ |
| file://:0:0:0:0 | [ | [ |
| file://:0:0:0:0 | \\0 | 0 |
| file://:0:0:0:0 | \\0 | 0 |
| file://:0:0:0:0 | \\D | D |
@@ -221,8 +207,6 @@ regExpNormalCharValue
| file://:0:0:0:0 | \| | \| |
| file://:0:0:0:0 | ] | ] |
| file://:0:0:0:0 | ] | ] |
| file://:0:0:0:0 | ] | ] |
| file://:0:0:0:0 | ]a-f] | ]a-f] |
| file://:0:0:0:0 | _ | _ |
| file://:0:0:0:0 | a | a |
| file://:0:0:0:0 | a | a |
@@ -236,7 +220,7 @@ regExpNormalCharValue
| file://:0:0:0:0 | a | a |
| file://:0:0:0:0 | a | a |
| file://:0:0:0:0 | a | a |
| file://:0:0:0:0 | a | a |
| file://:0:0:0:0 | a-f] | a-f] |
| file://:0:0:0:0 | abc | abc |
| file://:0:0:0:0 | abc | abc |
| file://:0:0:0:0 | abc | abc |
@@ -256,7 +240,6 @@ regExpNormalCharValue
| file://:0:0:0:0 | b | b |
| file://:0:0:0:0 | b | b |
| file://:0:0:0:0 | b | b |
| file://:0:0:0:0 | b | b |
| file://:0:0:0:0 | bar | bar |
| file://:0:0:0:0 | bar | bar |
| file://:0:0:0:0 | c | c |