C++: Implement POSIX equivalence classes

This commit is contained in:
copilot-swe-agent[bot]
2026-07-23 10:24:06 +00:00
committed by GitHub
parent 545d87a178
commit 12dc4b250f
4 changed files with 62 additions and 58 deletions

View File

@@ -53,6 +53,10 @@ private newtype TRegExpParent =
/** A POSIX collating symbol */
TRegExpPosixCollatingSymbol(RegExp re, int start, int end) {
re.posixStyleCollatingSymbol(start, end, _)
} or
/** A POSIX equivalence class */
TRegExpPosixEquivalenceClass(RegExp re, int start, int end) {
re.posixStyleEquivalenceClass(start, end, _)
}
/** An implementation that satisfies the RegexTreeView signature. */
@@ -143,6 +147,8 @@ private module Impl implements RegexTreeViewSig {
this = TRegExpSpecialChar(re, start, end)
or
this = TRegExpPosixCollatingSymbol(re, start, end)
or
this = TRegExpPosixEquivalenceClass(re, start, end)
}
/**
@@ -185,6 +191,8 @@ private module Impl implements RegexTreeViewSig {
result = this.(RegExpSpecialChar).getChild(i)
or
result = this.(RegExpPosixCollatingSymbol).getChild(i)
or
result = this.(RegExpPosixEquivalenceClass).getChild(i)
}
/**
@@ -1131,6 +1139,16 @@ private module Impl implements RegexTreeViewSig {
string getName() { re.posixStyleCollatingSymbol(start, end, result) }
}
additional class RegExpPosixEquivalenceClass extends RegExpTerm, TRegExpPosixEquivalenceClass {
RegExpPosixEquivalenceClass() { this = TRegExpPosixEquivalenceClass(re, start, end) }
override RegExpTerm getChild(int i) { none() }
override string getAPrimaryQlClass() { result = "RegExpPosixEquivalenceClass" }
string getName() { re.posixStyleEquivalenceClass(start, end, result) }
}
class Top = RegExpParent;
/**

View File

@@ -105,6 +105,8 @@ abstract class RegExp extends StringLiteral {
this.posixStyleNamedCharacterProperty(x, y, _)
or
this.posixStyleCollatingSymbol(x, y, _)
or
this.posixStyleEquivalenceClass(x, y, _)
) and
pos >= x and
pos < y
@@ -143,6 +145,8 @@ abstract class RegExp extends StringLiteral {
this.posixStyleNamedCharacterProperty(x, y, _)
or
this.posixStyleCollatingSymbol(x, y, _)
or
this.posixStyleEquivalenceClass(x, y, _)
) and
e >= x and
e < y
@@ -176,6 +180,8 @@ abstract class RegExp extends StringLiteral {
or
this.posixStyleCollatingSymbol(start, end, _)
or
this.posixStyleEquivalenceClass(start, end, _)
or
exists(this.nonEscapedCharAt(start)) and end = start + 1
)
or
@@ -187,6 +193,8 @@ abstract class RegExp extends StringLiteral {
or
this.posixStyleCollatingSymbol(start, end, _)
or
this.posixStyleEquivalenceClass(start, end, _)
or
exists(this.nonEscapedCharAt(start)) and
end = start + 1 and
not this.getChar(start) = "]"
@@ -344,6 +352,21 @@ abstract class RegExp extends StringLiteral {
name = this.getText().substring(start + 2, end - 2)
}
/** Matches a POSIX equivalence class such as `[=a=]` within a character class. */
predicate posixStyleEquivalenceClass(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
@@ -406,6 +429,8 @@ abstract class RegExp extends StringLiteral {
this.posixStyleNamedCharacterProperty(x, y, _)
or
this.posixStyleCollatingSymbol(x, y, _)
or
this.posixStyleEquivalenceClass(x, y, _)
) and
index in [x + 1 .. y - 2]
)
@@ -423,6 +448,8 @@ abstract class RegExp extends StringLiteral {
this.posixStyleNamedCharacterProperty(x, y, _)
or
this.posixStyleCollatingSymbol(x, y, _)
or
this.posixStyleEquivalenceClass(x, y, _)
) and
start >= x and
end <= y

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
@@ -206,12 +188,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] [A-F[[.b.]]a-f]
#-----| 0 -> [RegExpCharacterClass] [A-F[[.b.]]
@@ -280,6 +258,10 @@
#-----| 2 -> [RegExpOpt] c?
#-----| 3 -> [RegExpConstant, RegExpNormalChar] d
#-----| [RegExpPosixEquivalenceClass] [=b=]
#-----| [RegExpPosixEquivalenceClass] [=a=]
#-----| [RegExpPosixCollatingSymbol] [.b.]
#-----| [RegExpPosixCollatingSymbol] [.a.]
@@ -351,19 +333,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 -> [RegExpPosixEquivalenceClass] [=b=]
#-----| [RegExpCharacterClass] [[=a=]
#-----| 0 -> [RegExpConstant, RegExpNormalChar] [
#-----| 1 -> [RegExpConstant, RegExpNormalChar] =
#-----| 2 -> [RegExpConstant, RegExpNormalChar] a
#-----| 3 -> [RegExpConstant, RegExpNormalChar] =
#-----| [RegExpCharacterClass] [[=a=]]
#-----| 0 -> [RegExpPosixEquivalenceClass] [=a=]
#-----| [RegExpCharacterClass] [A-F[[.b.]]
#-----| 0 -> [RegExpCharacterRange] A-F

View File

@@ -29,10 +29,6 @@ term
| file://:0:0:0:0 | .* | RegExpStar |
| file://:0:0:0:0 | : | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | :+ | RegExpPlus |
| 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 | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | A | RegExpConstant,RegExpNormalChar |
| file://:0:0:0:0 | A | RegExpConstant,RegExpNormalChar |
@@ -52,23 +48,22 @@ 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 | [ | 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=] | RegExpPosixEquivalenceClass |
| file://:0:0:0:0 | [=b=] | RegExpPosixEquivalenceClass |
| 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.]]a-f] | RegExpSequence |
| 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 | [[:alpha:][:digit:]] | RegExpCharacterClass |
| file://:0:0:0:0 | [[:alpha:]] | RegExpCharacterClass |
| file://:0:0:0:0 | [[:alpha:]][[:digit:]] | RegExpSequence |
| file://:0:0:0:0 | [[:digit:]] | RegExpCharacterClass |
| 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 | [[a-f] | RegExpCharacterClass |
| file://:0:0:0:0 | [[a-f]A-F] | RegExpSequence |
| file://:0:0:0:0 | [\\0] | RegExpCharacterClass |
@@ -114,8 +109,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 |
@@ -129,7 +122,6 @@ 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 |
@@ -137,6 +129,7 @@ term
| 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-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 |
@@ -162,7 +155,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 |
@@ -192,10 +184,6 @@ regExpNormalCharValue
| 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 |
| file://:0:0:0:0 | A | A |
@@ -210,8 +198,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 | [ | [ |
| file://:0:0:0:0 | \\0 | 0 |
| file://:0:0:0:0 | \\0 | 0 |
| file://:0:0:0:0 | \\D | D |
@@ -234,8 +220,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 |
@@ -249,7 +233,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 | a-f] | a-f] |
| file://:0:0:0:0 | abc | abc |
| file://:0:0:0:0 | abc | abc |
@@ -270,7 +254,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 |