Skip to content

Commit 9d3f22c

Browse files
committed
fixed code bounds detection
1 parent 65f1b89 commit 9d3f22c

File tree

7 files changed

+313
-164
lines changed

7 files changed

+313
-164
lines changed

README.rst

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,11 @@ dependencies
5757

5858
* Java 1.7 or later
5959

60-
* Open Fortran Parser 0.8.4-2
60+
* Open Fortran Parser 0.8.4-3
6161

6262
https://github.com/mbdevpl/open-fortran-parser/releases
6363

64-
This is a patched version of OFP. Specifically, `FortranParserActionPrint` class in OFP
65-
could not be properly subclassed due to access levels of members of that class, so for example
66-
writing my own printer would introduce a lot of code duplication. Patch resolves this,
67-
without affecting any functionality.
68-
69-
The patch also resolves an issue when compiling with recent GCC versions.
64+
This is a patched version of OFP. The list of changes is available at the above link.
7065

7166
* ANTRL 3.3 (dependency of Open Fortran Parser)
7267

@@ -95,7 +90,7 @@ Build:
9590
ant
9691
export CLASSPATH="${CLASSPATH}:$(pwd)/dist/*"
9792
98-
This will create a `.jar` file in `dist` directory.
93+
This will create a `.jar` file in `dist` directory, and add it to the Java classpath.
9994

10095

10196
how to run
@@ -153,6 +148,9 @@ Inside the :xml:`<file>`, there might be one or many of the following nodes:
153148
Each of which has :xml:`<header>` and :xml:`<body>`.
154149
Additionally, :xml:`<module>` has :xml:`<members>`.
155150

151+
The contents of the header depend on the type of the node. For example, in case of subroutines,
152+
it contains list of parameters.
153+
156154
In the body, a special node :xml:`<specification>`, followed by a collection of statements can be found.
157155

158156
The :xml:`<specification>` contains a collection of :xml:`<declaraion>` nodes.
@@ -173,21 +171,26 @@ It has :xml:`<lower-bound>`, :xml:`<upper-bound>` and :xml:`<step>`.
173171

174172
In the header of :xml:`<if>`, an expression is present.
175173

176-
Expressions are built from the :xml:`<operation>` nodes, each of which contains a collection of
177-
:xml:`<operand>` and :xml:`<operator>` nodes. Each operand can be also an expression,
178-
or a simple node like:
174+
Expression might be a single node like:
179175

180176
* :xml:`<name>`
181177
* :xml:`<literal>`
182178
* ...
183179

180+
More complex expressions are built from the :xml:`<operation>` nodes, each of which contains
181+
a collection of :xml:`<operand>` and :xml:`<operator>` nodes. Each operand constains an expression.
182+
184183
All simple statements are using :xml:`<statement>` node, which wraps around nodes like:
185184

186185
* :xml:`<assignment>`
187186
* :xml:`<call>`
188187
* :xml:`<open>`
189188
* :xml:`<close>`
190189
* :xml:`<write>`
190+
* :xml:`<format>`
191+
* :xml:`<print>`
192+
* :xml:`<allocate>`
193+
* :xml:`<deallocate>`
191194
* :xml:`<return>`
192195
* :xml:`<stop>`
193196
* :xml:`<continue>`

src/fortran/ofp/XMLPrinter.java

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.w3c.dom.Attr;
1010
import org.w3c.dom.Element;
1111

12+
import fortran.ofp.parser.java.CodeBounds;
1213
import fortran.ofp.parser.java.IFortranParser;
1314
import fortran.ofp.parser.java.TokensList;
1415

@@ -2358,43 +2359,9 @@ public void dummy_arg_list(int count) {
23582359
contextClose();
23592360
}
23602361

2361-
protected void printTokens(Token... tokens) {
2362-
for (Token token : tokens) {
2363-
if (token == null) {
2364-
System.err.println("token is null");
2365-
continue;
2366-
}
2367-
int line = token.getLine();
2368-
int colBegin = token.getCharPositionInLine();
2369-
String text = token.getText();
2370-
int colEnd = colBegin + text.length();
2371-
System.err.println(filename + "@" + line + ":" + colBegin + "~" + colEnd + ": \"" + text + "\"");
2372-
}
2373-
/*
2374-
try {
2375-
TokensList tokens = new TokensList(new File(filename), false);
2376-
System.err.println("found tokens: " + tokens);
2377-
} catch (IOException e) {
2378-
}
2379-
*/
2380-
}
2381-
23822362
public void end_subroutine_stmt(Token label, Token keyword1, Token keyword2, Token name, Token eos) {
23832363
contextCloseAllInner("subroutine");
2384-
//System.err.println(Arrays.toString(getBounds(context)));
2385-
//updateBounds(name);
2386-
//updateBounds(eos);
2387-
//System.err.println(Arrays.toString(getBounds(context)));
2388-
System.err.println("end subroutine statments");
23892364
super.end_subroutine_stmt(label, keyword1, keyword2, name, eos);
2390-
System.err.println(Arrays.toString(getBounds(context)));
2391-
System.err.println(Arrays.toString(getBounds(context)));
2392-
updateBounds(label, keyword1, keyword2, name, eos);
2393-
System.err.println(Arrays.toString(getBounds(context)));
2394-
printTokens(label, keyword1, keyword2, name, eos);
2395-
System.err.println(Arrays.toString(getBounds(context)));
2396-
//updateBounds(eos);
2397-
//System.err.println(Arrays.toString(getBounds(context)));
23982365
contextClose();
23992366
}
24002367

src/fortran/ofp/XMLPrinterBase.java

Lines changed: 54 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.w3c.dom.NodeList;
2525

2626
import fortran.ofp.parser.java.TokensList;
27+
import fortran.ofp.parser.java.CodeBounds;
2728
import fortran.ofp.parser.java.FortranLexer;
2829
import fortran.ofp.parser.java.FortranParserActionPrint;
2930
import fortran.ofp.parser.java.IFortranParser;
@@ -361,8 +362,11 @@ protected void setAttribute(String name, Object value, Element context) {
361362
else if (value instanceof Token) {
362363
Token token = (Token) value;
363364
valueString = token.getText();
364-
if (verbosity >= 100)
365-
updateBounds(context, token);
365+
if (verbosity >= 100) {
366+
CodeBounds bounds = new CodeBounds(context);
367+
bounds.extend(token);
368+
bounds.persist(context);
369+
}
366370
} else
367371
valueString = value.toString();
368372
context.setAttribute(name, valueString);
@@ -376,11 +380,6 @@ protected void setAttribute(String name, Object value) {
376380
setAttribute(name, value, context);
377381
}
378382

379-
protected static String Y_MIN = "line_begin";
380-
protected static String X_MIN = "col_begin";
381-
protected static String Y_MAX = "line_end";
382-
protected static String X_MAX = "col_end";
383-
384383
/**
385384
* Return null if (line, col) not in this context, and when it cannot be determined if it is in it or not.
386385
*
@@ -393,141 +392,55 @@ public Element findContext(Element context, int line, int col) {
393392
continue;
394393
return containingNode;
395394
}
396-
Integer[] bounds = getBounds(context);
397-
Integer line_begin = bounds[0], col_begin = bounds[1], line_end = bounds[2], col_end = bounds[3];
398-
if (line_begin == null || col_begin == null || line_end == null || col_end == null)
395+
CodeBounds bounds = new CodeBounds(context);
396+
if (bounds.begin == null || bounds.end == null)
399397
return null;
400-
if (line < line_begin || line > line_end)
398+
if (line < bounds.begin.line || line > bounds.end.line)
401399
return null;
402-
if (line > line_begin && line < line_end)
400+
if (line > bounds.begin.line && line < bounds.end.line)
403401
return context;
404-
if (line == line_begin)
405-
return col >= col_begin ? context : null;
406-
if (line == line_end)
407-
return col <= col_end ? context : null;
402+
if (line == bounds.begin.line)
403+
return col >= bounds.begin.col ? context : null;
404+
if (line == bounds.end.line)
405+
return col <= bounds.end.col ? context : null;
408406
throw new RuntimeException();
409407
}
410408

411409
public int findPosition(Element context, int line, int col) {
412410
int index = -1;
413411
for (Element node : contextNodes(context)) {
414-
Integer[] bounds = getBounds(node);
415-
Integer line_begin = bounds[0], col_begin = bounds[1], line_end = bounds[2], col_end = bounds[3];
412+
CodeBounds bounds = new CodeBounds(node);
416413
++index;
417-
if (line_begin == null || col_begin == null || line_end == null || col_end == null)
414+
if (bounds.begin == null || bounds.end == null)
418415
continue;
419-
if (line < line_begin)
416+
if (line < bounds.begin.line)
420417
return index;
421-
if (line > line_end)
418+
if (line > bounds.end.line)
422419
continue;
423-
if (line == line_begin)
424-
if (col < col_begin)
420+
if (line == bounds.begin.line)
421+
if (col < bounds.begin.col)
425422
return index;
426-
if (col > col_end)
423+
if (col > bounds.end.col)
427424
continue;
428-
throw new RuntimeException("looking for (" + line + "," + col + ")" + " within bounds (" + line_begin + ","
429-
+ col_begin + ")" + " .. (" + line_end + "," + col_end + ")" + "\n" + "of " + contextString(node)
425+
throw new RuntimeException("looking for (" + line + "," + col + ")" + " within bounds " + bounds + "\n" + "of " + contextString(node)
430426
+ "\n" + "subnode of " + contextString(context));
431427
}
432428
return contextNodesCount(context);
433429
}
434430

435-
protected Integer[] getBounds(Element context) {
436-
Integer lineBegin = context.hasAttribute(Y_MIN) ? Integer.valueOf(context.getAttribute(Y_MIN)) : null;
437-
Integer colBegin = context.hasAttribute(X_MIN) ? Integer.valueOf(context.getAttribute(X_MIN)) : null;
438-
Integer lineEnd = context.hasAttribute(Y_MAX) ? Integer.valueOf(context.getAttribute(Y_MAX)) : null;
439-
Integer colEnd = context.hasAttribute(X_MAX) ? Integer.valueOf(context.getAttribute(X_MAX)) : null;
440-
return new Integer[] { lineBegin, colBegin, lineEnd, colEnd };
441-
}
442-
443-
protected Integer[] getBounds(Token token) {
444-
Integer line = token.getLine();
445-
Integer colBegin = token.getCharPositionInLine();
446-
Integer colEnd = colBegin + token.getText().length();
447-
return new Integer[] { line, colBegin, line, colEnd };
448-
}
449-
450-
protected void updateBounds(Element context, Integer[] bounds) {
451-
updateBounds(context, bounds[0], bounds[1], bounds[2], bounds[3]);
452-
}
453-
454-
protected void updateBounds(Element context, Integer new_line_begin, Integer new_col_begin, Integer new_line_end,
455-
Integer new_col_end) {
456-
Integer[] bounds = getBounds(context);
457-
Integer line_begin = bounds[0], col_begin = bounds[1], line_end = bounds[2], col_end = bounds[3];
458-
459-
if (new_line_begin == null && new_col_begin == null && new_line_end == null && new_col_end == null)
460-
return;
461-
if (new_line_begin == null || new_col_begin == null || new_line_end == null || new_col_end == null)
462-
throw new IllegalArgumentException("the implementation of this method is all-or-nothing");
463-
464-
boolean updateLineBegin = false;
465-
boolean updateColBegin = false;
466-
boolean updateLineEnd = false;
467-
boolean updateColEnd = false;
468-
469-
if (line_begin == null && col_begin == null && line_end == null && col_end == null) {
470-
updateLineBegin = true;
471-
updateColBegin = true;
472-
updateLineEnd = true;
473-
updateColEnd = true;
474-
} else if (line_begin == null || col_begin == null || line_end == null || col_end == null)
475-
throw new IllegalArgumentException("the implementation of this method is all-or-nothing");
476-
else {
477-
if (new_line_begin < line_begin)
478-
updateLineBegin = true;
479-
480-
if (updateLineBegin)
481-
updateColBegin = true;
482-
else if (new_line_begin == line_begin && new_col_begin < col_begin)
483-
updateColBegin = true;
484-
485-
if (new_line_end > line_end)
486-
updateLineEnd = true;
487-
488-
if (updateLineEnd)
489-
updateColEnd = true;
490-
else if (new_line_end == line_end && new_col_end > col_end)
491-
updateColEnd = true;
492-
493-
if (new_line_end == line_end && updateColEnd) {
494-
System.err.println("updating col_end in " + contextString(context));
495-
}
496-
497-
}
498-
499-
if (updateLineBegin)
500-
context.setAttribute(Y_MIN, new_line_begin.toString());
501-
if (updateColBegin)
502-
context.setAttribute(X_MIN, new_col_begin.toString());
503-
if (updateLineEnd)
504-
context.setAttribute(Y_MAX, new_line_end.toString());
505-
if (updateColEnd)
506-
context.setAttribute(X_MAX, new_col_end.toString());
507-
508-
if (new_line_end == line_end && updateColEnd) {
509-
System.err.println("updated col_end in " + contextString(context));
510-
}
511-
}
512-
513-
protected void updateBounds(Element context, Token... newTokens) {
514-
for (Token newToken : newTokens) {
515-
if (newToken == null)
516-
continue;
517-
updateBounds(context, getBounds(newToken));
518-
}
519-
}
520-
521-
protected void updateBounds(Token... newTokens) {
522-
updateBounds(context, newTokens);
523-
}
524-
525431
protected void propagateBounds(Element context) {
526432
ArrayList<Element> nodes = contextNodes(context);
527433
for (Element node : nodes) {
528434
propagateBounds(node);
529-
if (context != root)
530-
updateBounds(context, getBounds(node));
435+
if (context == root)
436+
continue;
437+
CodeBounds bounds = new CodeBounds(node);
438+
if (bounds.begin == null)
439+
continue;
440+
CodeBounds rootBounds = new CodeBounds(context);
441+
rootBounds.extend(bounds.begin);
442+
rootBounds.extend(bounds.end);
443+
rootBounds.persist(context);
531444
}
532445
}
533446

@@ -620,6 +533,27 @@ protected void printParameter(Token param, String name) {
620533
setAttribute(name, param);
621534
}
622535

536+
protected void printTokens(Token... tokens) {
537+
for (Token token : tokens) {
538+
if (token == null) {
539+
System.err.println("token is null");
540+
continue;
541+
}
542+
int line = token.getLine();
543+
int colBegin = token.getCharPositionInLine();
544+
String text = token.getText();
545+
int colEnd = colBegin + text.length();
546+
System.err.println(filename + "@" + line + ":" + colBegin + "~" + colEnd + ": \"" + text + "\"");
547+
}
548+
/*
549+
try {
550+
TokensList tokens = new TokensList(new File(filename), false);
551+
System.err.println("found tokens: " + tokens);
552+
} catch (IOException e) {
553+
}
554+
*/
555+
}
556+
623557
/**
624558
* Insert raw tokens from current file into given context.
625559
*/
@@ -658,7 +592,8 @@ protected void insertTokens(Element context, int tokenType, String tokenContextN
658592

659593
Element tokenNode = contextOpen(tokenContextName);
660594
setAttribute(tokenTextAttributeName, token.getText());
661-
updateBounds(token);
595+
CodeBounds bounds = new CodeBounds(token);
596+
bounds.persist(tokenNode); // updateBounds(token);
662597
contextClose();
663598

664599
tokenNode.getParentNode().removeChild(tokenNode);

0 commit comments

Comments
 (0)