Skip to content

Commit 331bfd6

Browse files
author
jdf
committed
Fix bug1532, and in the process utterly destroy mode-detection problems by moving mode detection out of the parser, and into Java-land (in PdePreprocessor.java).
1 parent 9fc70e7 commit 331bfd6

File tree

6 files changed

+222
-61
lines changed

6 files changed

+222
-61
lines changed

app/grammars/pde.g

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ options {
1717
// debugging messages, however, doing so disables highlighting errors
1818
// in the editor.
1919
defaultErrorHandler = false; //true;
20-
21-
// permit mode-detection heuristics, below
22-
k=3;
2320
}
2421

2522
tokens {
@@ -50,35 +47,12 @@ tokens {
5047
}
5148

5249
pdeProgram
53-
// only java mode programs will have their own public classes or
54-
// imports (and they must have at least one)
55-
: ( "public" "class" | "import" ) => javaProgram
56-
{ pp.setMode(PdePreprocessor.Mode.JAVA); }
57-
58-
// the syntactic predicate here looks for any minimal (thus
59-
// the non-greedy qualifier) number of fields, followed by
60-
// the tokens that represent the definition of loop() or
61-
// some other member function. java mode programs may have such
62-
// definitions, but they won't reach this point, having already been
63-
// selected in the previous alternative. static mode programs
64-
// don't have member functions.
65-
//
66-
// The typeSpec match causes ANTLR to emit a warning about potentially
67-
// exiting the nongreedy match incorrectly, but I haven't found a case
68-
// of that in practice. Please report such a case!
69-
| ( (options{greedy=false;}: possiblyEmptyField)* typeSpec[false] IDENT LPAREN )
70-
=> activeProgram
71-
{ pp.setMode(PdePreprocessor.Mode.ACTIVE); }
72-
50+
:
7351
// Some programs can be equally well interpreted as STATIC or ACTIVE;
7452
// this forces the parser to prefer the STATIC interpretation.
75-
| (staticProgram) => staticProgram
53+
(staticProgram) => staticProgram
7654
{ pp.setMode(PdePreprocessor.Mode.STATIC); }
7755

78-
// Some correct ACTIVE programs (using lots of modifiers and/or
79-
// type arguments) are not caught by the heuristic predicate above,
80-
// so we at least catch those here so that the STATIC catch-all, below,
81-
// won't choke on it.
8256
| (activeProgram) => activeProgram
8357
{ pp.setMode(PdePreprocessor.Mode.ACTIVE); }
8458

app/src/processing/app/preproc/PdePreprocessor.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.util.ArrayList;
3939
import java.util.Arrays;
4040
import java.util.List;
41+
import java.util.regex.Pattern;
4142
import processing.app.Preferences;
4243
import processing.app.antlr.PdeLexer;
4344
import processing.app.antlr.PdeRecognizer;
@@ -386,6 +387,14 @@ static String substituteUnicode(String program) {
386387
return new String(p2, 0, index);
387388
}
388389

390+
private static final Pattern PUBLIC_CLASS = Pattern.compile(
391+
"(^|;)\\s*public\\s+class", Pattern.MULTILINE);
392+
393+
private static final Pattern FUNCTION_DECL = Pattern
394+
.compile(
395+
"(^|;)\\s*((public|private|protected|final|static)\\s+)*(void|int|float|double|String|char|byte)(\\s*\\[\\s*\\])?\\s+[a-zA-Z0-9]+\\s*\\(",
396+
Pattern.MULTILINE);
397+
389398
/**
390399
* preprocesses a pde file and writes out a java file
391400
* @return the class name of the exported Java
@@ -436,10 +445,16 @@ private String write(final String program, final PrintWriter stream)
436445
//
437446
parser.setASTNodeClass("antlr.ExtendedCommonASTWithHiddenTokens");
438447

439-
// start parsing at the compilationUnit non-terminal
440-
//
441-
parser.pdeProgram();
442-
448+
if (PUBLIC_CLASS.matcher(program).find()) {
449+
setMode(Mode.JAVA);
450+
parser.javaProgram();
451+
} else if (FUNCTION_DECL.matcher(program).find()) {
452+
setMode(Mode.ACTIVE);
453+
parser.activeProgram();
454+
} else {
455+
parser.pdeProgram();
456+
}
457+
443458
// set up the AST for traversal by PdeEmitter
444459
//
445460
ASTFactory factory = new ASTFactory();

app/test/resources/bug1532.pde

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
import processing.video.*;
2+
import processing.opengl.*;
3+
4+
5+
6+
final int l=50;
7+
final int hx=15;
8+
final int hy=18;
9+
final int dx=int((l+l*cos(PI/3))*hx);
10+
final int dy=int(l*sin(PI/3)*hy);
11+
12+
boolean cheatScreen=false;
13+
String shoot="shoot/";
14+
final int fr=24;
15+
PImage tile1,tile2;
16+
Capture cam;
17+
18+
19+
flatCube[][] grid;
20+
21+
void setup() {
22+
try {
23+
quicktime.QTSession.open();
24+
}
25+
catch (quicktime.QTException qte) {
26+
qte.printStackTrace();
27+
}
28+
29+
size (dx,dy,OPENGL);
30+
int d=day();
31+
int m=month();
32+
int y=year();
33+
int h=hour();
34+
int mp=minute();
35+
int ms=second();
36+
37+
shoot=shoot+y+m+d+h+mp+ms;
38+
39+
cam = new Capture(this, hx, hy, fr);
40+
frameRate(fr);
41+
42+
tile1=loadImage("111.png");
43+
tile2=loadImage("122.png");
44+
tile3=loadImage("001.png");
45+
grid= new flatCube[hx][hy];
46+
for (int j=0; j<hy;j++) {
47+
for (int i=0; i<hx; i++) {
48+
49+
switch ((i+j) %3 ){
50+
case 0: grid[i][j]= new flatCube(tile1,0) break;
51+
case 1: grid[i][j]= new flatCube(tile2,0); break;
52+
case 2: grid[i][j]= new flatCube(tile3,0); break;
53+
}
54+
}
55+
}
56+
57+
noStroke();
58+
}
59+
60+
public void captureEvent(Capture c) {
61+
c.read();
62+
}
63+
64+
65+
void draw() {
66+
67+
background (0,0,0);
68+
float x=mouseX;
69+
float y=mouseY;
70+
int signx=-1;
71+
int signy=-1;
72+
int cx=0;
73+
int cy=0;
74+
color c;
75+
float rot=0;
76+
77+
for (int j=0; j<hy;j++) {
78+
pushMatrix();
79+
for (int i=0; i<hx; i++) {
80+
c=cam.pixels[i+j*hx];
81+
pushMatrix();
82+
if (frameCount % 3 == 0 ) {
83+
rot=PI/3*int(random(0,7));
84+
cx=int (random(0,hx));
85+
cy=int (random(0,hy));
86+
}
87+
if ((cx==i)&&(cy==j)) grid[i][j].show(rot,c); else grid[i][j].show(c);
88+
popMatrix();
89+
translate (l+l*cos(PI/3),signx*l*sin(PI/3));
90+
91+
92+
signx=-signx;
93+
}
94+
popMatrix();
95+
signy=-signy;
96+
translate (signy*(l+l*cos(PI/3)),l*sin(PI/3));
97+
}
98+
99+
100+
if (cheatScreen) {
101+
image(cam, 0, 0);
102+
}
103+
}
104+
105+
106+
public void keyPressed() {
107+
108+
switch (key) {
109+
case 'c':
110+
cheatScreen = !cheatScreen;
111+
break;
112+
case 'g':
113+
saveFrame(shoot+"######.png");
114+
println ("saved "+l);
115+
break;
116+
case 'm':
117+
cam.settings();
118+
break;
119+
120+
case 'q':
121+
exit();
122+
break;
123+
}
124+
}
125+
126+
class flatCube {
127+
128+
129+
PImage tile;
130+
float rot;
131+
flatCube (PImage i, float r) {
132+
tile=i;
133+
rot=r;
134+
}
135+
136+
void show (float r, color c){
137+
rot=r;
138+
show(c);
139+
}
140+
141+
void show (color c) {
142+
pushMatrix();
143+
translate(l,l*sin(PI/3));
144+
rotateZ(rot);
145+
translate(-l,-l*sin(PI/3));
146+
tint(c);
147+
image (tile,0,0);
148+
popMatrix();
149+
}
150+
151+
void show(int l,int a, color c) {
152+
noStroke();
153+
pushMatrix();
154+
fill(c,a);
155+
quad(0,0, l,0, l+l*cos(PI/3),l*sin(PI/3), l*cos(PI/3),l*sin(PI/3) );
156+
rotateZ(PI/3);
157+
fill(c,a);
158+
quad(0,0, l,0, l+l*cos(PI/3),l*sin(PI/3), l*cos(PI/3),l*sin(PI/3) );
159+
translate(l+l*cos(PI/3),l*sin(PI/3));
160+
rotateZ(-TWO_PI/3);
161+
fill (c,a);
162+
quad(0,0, l,0, l+l*cos(PI/3),l*sin(PI/3), l*cos(PI/3),l*sin(PI/3) );
163+
164+
popMatrix();
165+
}
166+
167+
}
168+
169+
170+
171+

app/test/resources/bug1534.expected

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@ import java.util.zip.*;
1616
import java.util.regex.*;
1717

1818
public class bug1534 extends PApplet {
19-
public void setup() {
19+
2020
char c = '\"';
21-
noLoop();
22-
}
2321
static public void main(String args[]) {
2422
PApplet.main(new String[] { "--bgcolor=null", "bug1534" });
2523
}

app/test/resources/bug4.expected

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,25 @@
1-
import processing.core.*;
2-
import processing.xml.*;
3-
4-
import java.applet.*;
5-
import java.awt.Dimension;
6-
import java.awt.Frame;
7-
import java.awt.event.MouseEvent;
8-
import java.awt.event.KeyEvent;
9-
import java.awt.event.FocusEvent;
10-
import java.awt.Image;
11-
import java.io.*;
12-
import java.net.*;
13-
import java.text.*;
14-
import java.util.*;
15-
import java.util.zip.*;
16-
import java.util.regex.*;
17-
18-
public class bug4 extends PApplet {
19-
public void setup() {
1+
import processing.core.*;
2+
import processing.xml.*;
3+
4+
import java.applet.*;
5+
import java.awt.Dimension;
6+
import java.awt.Frame;
7+
import java.awt.event.MouseEvent;
8+
import java.awt.event.KeyEvent;
9+
import java.awt.event.FocusEvent;
10+
import java.awt.Image;
11+
import java.io.*;
12+
import java.net.*;
13+
import java.text.*;
14+
import java.util.*;
15+
import java.util.zip.*;
16+
import java.util.regex.*;
17+
18+
public class bug4 extends PApplet {
19+
2020
int x = 12;
2121
float u = (PApplet.parseFloat(x)/width);
22-
noLoop();
23-
}
24-
static public void main(String args[]) {
25-
PApplet.main(new String[] { "--bgcolor=null", "bug4" });
26-
}
27-
}
22+
static public void main(String args[]) {
23+
PApplet.main(new String[] { "--bgcolor=null", "bug4" });
24+
}
25+
}

app/test/src/test/processing/parsing/ParserTests.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ public void bug763() {
182182

183183
@Test
184184
public void bug820() {
185-
expectCompilerException("bug820", "x1 is already defined in setup()", 21);
185+
expectCompilerException("bug820", "x1 is already defined in bug820", 21);
186186
}
187187

188188
@Test
@@ -260,6 +260,11 @@ public void bug1525() {
260260
expectGood("bug1525");
261261
}
262262

263+
@Test
264+
public void bug1532() {
265+
expectRecognitionException("bug1532", "unexpected token: break", 50);
266+
}
267+
263268
@Test
264269
public void bug1534() {
265270
expectGood("bug1534");

0 commit comments

Comments
 (0)