-
Notifications
You must be signed in to change notification settings - Fork 19
Description
When saving while, for, repeat, or maybe other statements, some problems occur. For example, we have the following algorithm:
ALGORITHM A1 IN ST:
VAR_TEMP
Index : INT;
Sum: INT;
END_VAR
Index := 0;
Sum := 0;
WHILE Index < 10 DO
Sum := Sum + Index;
Index := Index + 1;
END_WHILE;
END_ALGORITHM
After reopening MPS, it shows the algorithm in a changed way:
ALGORITHM A1 IN ST:
VAR_TEMP
Index : INT;
Sum : INT;
END_VAR
Index := 0;
Sum := 0;
WHILE Index < 10 DO
no statements
END_WHILE;
Sum := Sum + Index;
Index := Index + 2;
END_ALGORITHM
And when trying to parse this algorithm in code: org.fbme.lib.iec61499.parser.STConverter.parseStatementList, the org.antlr.v4.runtime.InputMismatchException occurs because input text is Index := 0; Sum := 0; WHILE Index < 10 DO Sum := Sum + Index; Index := Index + 1; END_WHILE; and the error is at the 49th symbol - after WHILE Index < 10 DO
I think the problem is in org.fbme.lib.iec61499.stringify.PrinterBase.escapeXML:
text = text.replace("\n", " ")
text = text.replace("\"", """)
text = text.replace("&", "&")
After "\n" is replaced by , the "&" is replaced by &. So, "\n" is replaced by &#10; and it is written to a file (saved)
Returning to the text when the ANTLR exception is thrown. The parser reads the saved model with our algorithm. After that, the model is unescaped in org.fbme.lib.iec61499.parser.BasicFBTypeConverter.AlgorithmConverter.extractDeclarationBody:
val stText = stBodyElement.getAttributeValue("Text")?.unescapeXML()
Let's look at unescapeXML() block:
.replace(" ", "\n")
.replace(""", "\"")
.replace("&", "&")
As you see, our &#10; is replaced by . After that, ANTLR throwsorg.antlr.v4.runtime.InputMismatchException.
I believe that, in order to address this issue, it would be advisable to adjust the order of escaping in the following manner: org.fbme.lib.iec61499.stringify.PrinterBase.escapeXML
text = text.replace("\n", " ")
text = text.replace("\"", """)
text = text.replace("&", "&") // this line must be the first in replace commands