rascal icon indicating copy to clipboard operation
rascal copied to clipboard

two regular expressions in the same comprehension breaks

Open jurgenvinju opened this issue 12 years ago • 12 comments

In the code below Rascal complains about a redeclared variable n, but only if the second regular expression is there (/rascal/ := f). A nested comprehension for the same computation works nicely.

rascal>{ <toInt(n), f> | /\s*<n:[0-9]+>\s*<f:\S+>/ <- raw, /rascal/ := f}
|stdin:///|(64,1,<1,64>,<1,65>): Redeclared variable: n

rascal>{<x,y> | <x,y> <- { <toInt(n), f> | /\s*<n:[0-9]+>\s*<f:\S+>/ <- raw}, /rascal/ := y}
rel[int, str]: {
  <1,"/unstable-updates/plugins/rascal_eclipse_0.5.2.201209211516.jar">,

jurgenvinju avatar Jan 14 '13 18:01 jurgenvinju

This works now:

rascal>{ <toInt(n), f> | /\s*<n:[0-9]+>\s*<f:\S+>/ := "99srascal", /rascal/ := f}
rel[int,str]: {<99,"srascal">}

DavyLandman avatar Nov 09 '15 11:11 DavyLandman

I've just noticed a similar behaviour with the if statement that generates the same error

if (/<pre:.*>\/\*/ := line && /\S/ := pre && /"(\w|\s)*/ !:= pre)
					commentLinesToIgnore +=1;

image

menego avatar Dec 05 '19 22:12 menego

This reproduces the bug:

module RegexBug

import IO;

void main() {
  line = "\"bla   /* hello */\"  ";
  ii = 0;
  
  if (/<pre:.*>\/\*/ := line && /\S/ := pre && /"(\w|\s)*/ !:= pre)
                    ii +=1;
                    
  println(ii);                    

}

jurgenvinju avatar Dec 06 '19 08:12 jurgenvinju

This does not have the bug, even though it should be functionality equivalent (replaced && by ,):

module RegexBug

import IO;

void main() {
  line = "\"bla   /* hello */\"  ";
  ii = 0;
  
  if (/<pre:.*>\/\*/ := line, /\S/ := pre, /"(\w|\s)*/ !:= pre)
                    ii +=1;
                    
  println(ii);                    

}

jurgenvinju avatar Dec 06 '19 08:12 jurgenvinju

@menego that gives you a workaround for today, and we have an hypothesis for the cause of the bug: an buggy interaction between the backtracking behavior of the && connective and the declaration behavior of regexps.

jurgenvinju avatar Dec 06 '19 08:12 jurgenvinju

Thank you very much, always super responsive :-) I already solved that by nesting the if statements but this is waaay cleaner and elegant.

menego avatar Dec 06 '19 08:12 menego

void d() {
  pre = "\"";
  if (_ <- [1,2] && /"(.)*/ !:= pre)
     println("ok");     
}

simplified.

jurgenvinju avatar Dec 06 '19 08:12 jurgenvinju

another delta gives some insight (replace implicit group by explicit group):

void d() {
  pre = "\"";
  if (_ <- [1,2] && /"<xxx:.>*/ !:= pre)
     println("ok");     
}

gives:

rascal>d()
Reloading module RegexBug
|project://rascal-test-project/src/RegexBug.rsc|(86,3,<7,32>,<7,35>): Redeclared variable: _1
Advice: |http://tutor.rascal-mpl.org/Errors/Static/RedeclaredVariable/RedeclaredVariable.html|
ok
rascal>d()
Reloading module RegexBug
|project://rascal-test-project/src/RegexBug.rsc|(90,3,<7,36>,<7,39>): Redeclared variable: xxx
Advice: |http://tutor.rascal-mpl.org/Errors/Static/RedeclaredVariable/RedeclaredVariable.html|
ok

jurgenvinju avatar Dec 06 '19 08:12 jurgenvinju

Flip the conditional and change the match:

void d() {
  pre = "\'";
  if (_ <- [1,2] && /"<xxx:.>*/ := pre)
     println("ok");     
}

still produces:

rascal>d()
|project://rascal-test-project/src/RegexBug.rsc|(89,3,<7,35>,<7,38>): Redeclared variable: xxx

means that the difference between !:= and := is irrelevant.

jurgenvinju avatar Dec 06 '19 08:12 jurgenvinju

Ok, this is a complex issue. The difference is still made by replacing && with , and it seems that a variable scope is not properly cleaned up before the second match is tried, and the second instance of xxx is declared again in the same scope.

The trouble with fixing this issue is that the code around && is brittle and highly dependent on the semantics and implementation details of binding patterns such as the ListPattern, the SetPattern and the basic TypedVariablePattern.

So this requires some further study.

jurgenvinju avatar Dec 06 '19 08:12 jurgenvinju

rascal>  if (_ <- [1,2] && /"<xxx2:.>*/ !:= "\"") println("ok");
|prompt:///|(37,3,<1,37>,<1,40>): Redeclared variable: xxx2
Advice: |https://www.rascal-mpl.org/docs/Rascal/Errors/CompileTimeErrors/RedeclaredVariable|

this is still an issue.

DavyLandman avatar Dec 04 '23 08:12 DavyLandman

See #1900 for progress; that fix is not correct yet.

jurgenvinju avatar Dec 21 '23 08:12 jurgenvinju