usethesource / rascal

The implementation of the Rascal meta-programming language (including interpreter, type checker, parser generator, compiler and JVM based run-time system)
http://www.rascal-mpl.org
Other
400 stars 77 forks source link

two regular expressions in the same comprehension breaks #101

Open jurgenvinju opened 11 years ago

jurgenvinju commented 11 years ago

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">,
DavyLandman commented 8 years ago

This works now:

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

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

jurgenvinju commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

@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.

menego commented 4 years ago

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

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

simplified.

jurgenvinju commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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.

DavyLandman commented 9 months ago
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.

jurgenvinju commented 9 months ago

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