fix: generate_data constraint steering fully repaired

Root cause: IF condition and EVALUATE WHEN parsing swallowed entire
line including THEN-body (e.g. '50 MOVE BIG...' instead of just '50').

Fix:
1. Single-line IF cond_text truncated at COBOL statement-starting keywords
   (MOVE/DISPLAY/COMPUTE/ADD/...)
2. Multi-line IF continuation loop also breaks on these keywords (was
   missing DISPLAY, READ, WRITE, CLOSE, OPEN, SEARCH, ...)
3. EVALUATE WHEN raw_val truncated at same keyword set
4. All raw-string escape sequences fixed (Python 3.12 SyntaxWarning)

Verification:
- IF single-line A>50: A=51(true)/12(false) previously A=01/00
- IF multi-line X>50: X=51(true)/12(false) previously not steered
- EVALUATE WHEN 1/2/OTHER: C=1/2/4 previously C=0/0/0
- IF AND compound: (A<=10,B<20), (A>10,B<20), (A>10,B>=20)
- IF >75: A=76(true)/12(false) previously not steered

R11 tests updated: BUG documentation replaced with real assertions.
13 suites / 0 FAIL.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
NB-076
2026-06-22 09:10:21 +08:00
parent 703e7afc8a
commit d8176ea07b
2 changed files with 40 additions and 14 deletions
+20 -1
View File
@@ -648,11 +648,23 @@ class _BrParser:
line = self.clean()
m = re.match(r'^IF\s+(.+?)(?:THEN)?\s*$', line)
cond_text = m.group(1).strip()
# Truncate at COBOL statement keywords (single-line IF body after condition)
_stmt_pat = (r'\s(?:MOVE|DISPLAY|COMPUTE|ADD|SUBTRACT|MULTIPLY|DIVIDE|STRING|UNSTRING|'
r'INITIALIZE|ACCEPT|CALL|PERFORM|EVALUATE|READ|WRITE|REWRITE|DELETE|START|'
r'INSPECT|SET|IF|ELSE|END-IF|GO\b|EXIT\b|STOP\s+RUN|GOBACK|CLOSE|OPEN|SEARCH)\b')
_stmt_starts = re.compile(_stmt_pat, re.IGNORECASE)
sm = _stmt_starts.search(cond_text)
if sm:
cond_text = cond_text[:sm.start()]
self.advance()
# Join continuation lines (multi-line IF conditions)
_cont_keywords = (r'THEN|ELSE|END-IF|MOVE|DISPLAY|COMPUTE|ADD|SUBTRACT|MULTIPLY|'
r'DIVIDE|STRING|UNSTRING|INITIALIZE|ACCEPT|CALL|PERFORM|EVALUATE|'
r'READ|WRITE|REWRITE|DELETE|START|INSPECT|SET|IF|GO\b|EXIT\b|'
r'STOP\s+RUN|GOBACK|CLOSE|OPEN|SEARCH')
while self.pos < len(self.lines):
peek = self.clean()
if re.match(r'^(THEN|ELSE|END-IF|MOVE|IF|PERFORM|EVALUATE|COMPUTE|CALL|STRING|UNSTRING|INITIALIZE|ADD|SUBTRACT|MULTIPLY|DIVIDE|GO\b|EXIT\b)', peek, re.IGNORECASE):
if re.match(r'^(' + _cont_keywords + r')', peek, re.IGNORECASE):
break
if peek.endswith('.'):
cond_text += ' ' + peek.rstrip('.')
@@ -696,6 +708,13 @@ class _BrParser:
m = re.match(r'^WHEN\s+(.+?)\s*$', line)
if m:
raw_val = m.group(1).strip().strip("'").strip('"')
# Truncate at COBOL statement keywords (single-line WHEN body after condition)
_eval_pat = (r'\s(?:MOVE|DISPLAY|COMPUTE|ADD|SUBTRACT|MULTIPLY|DIVIDE|STRING|UNSTRING|'
r'INITIALIZE|ACCEPT|CALL|PERFORM|EVALUATE|READ|WRITE|REWRITE|DELETE|START|'
r'INSPECT|SET|IF|ELSE|END-IF|GO\b|EXIT\b|STOP\b|GOBACK|CLOSE|OPEN|SEARCH)\b')
_eval_stmt = re.search(_eval_pat, raw_val, re.IGNORECASE)
if _eval_stmt:
raw_val = raw_val[:_eval_stmt.start()]
self.advance()
# Capture multi-line WHEN conditions (AND/OR continuation)
while self.pos < len(self.lines):