|
2 | 2 |
|
3 | 3 | import java.util.Optional; |
4 | 4 |
|
5 | | -import liquidjava.diagnostics.errors.LJError; |
6 | 5 | import liquidjava.diagnostics.errors.SyntaxError; |
7 | 6 | import liquidjava.processor.facade.AliasDTO; |
8 | 7 | import liquidjava.processor.facade.GhostDTO; |
|
13 | 12 | import org.antlr.v4.runtime.CharStreams; |
14 | 13 | import org.antlr.v4.runtime.CodePointCharStream; |
15 | 14 | import org.antlr.v4.runtime.CommonTokenStream; |
16 | | -import org.antlr.v4.runtime.RuleContext; |
17 | 15 | import org.antlr.v4.runtime.tree.ParseTree; |
18 | 16 | import rj.grammar.RJLexer; |
19 | 17 | import rj.grammar.RJParser; |
20 | 18 |
|
21 | 19 | public class RefinementsParser { |
22 | 20 |
|
23 | | - public static Expression createAST(String toParse, String prefix) throws LJError { |
24 | | - ParseTree pt = compile(toParse); |
| 21 | + /** |
| 22 | + * Parses a refinement expression from a string |
| 23 | + */ |
| 24 | + public static Expression createAST(String toParse, String prefix) throws SyntaxError { |
| 25 | + ParseTree pt = compile(toParse, "Invalid refinement expression, expected a logical predicate"); |
25 | 26 | CreateASTVisitor visitor = new CreateASTVisitor(prefix); |
26 | 27 | return visitor.create(pt); |
27 | 28 | } |
28 | 29 |
|
29 | 30 | /** |
30 | | - * The triple information of the ghost declaration in the order <type, name, list<type,name>> |
31 | | - * |
32 | | - * @param s |
| 31 | + * Parses the ghost declaration from the given string |
33 | 32 | */ |
34 | | - public static GhostDTO getGhostDeclaration(String s) throws LJError { |
35 | | - ParseTree rc = compile(s); |
| 33 | + public static GhostDTO parseGhostDeclaration(String toParse) throws SyntaxError { |
| 34 | + String errorMessage = "Invalid ghost declaration, expected e.g. @Ghost(\"int size\")"; |
| 35 | + ParseTree rc = compile(toParse, errorMessage); |
36 | 36 | GhostDTO g = GhostVisitor.getGhostDecl(rc); |
37 | 37 | if (g == null) |
38 | | - throw new SyntaxError("Invalid ghost declaration, expected e.g. @Ghost(\"int size\")", s); |
| 38 | + throw new SyntaxError(errorMessage, toParse); |
39 | 39 | return g; |
40 | 40 | } |
41 | 41 |
|
42 | | - public static AliasDTO getAliasDeclaration(String s) throws LJError { |
43 | | - CodePointCharStream input = CharStreams.fromString(s); |
44 | | - RJErrorListener err = new RJErrorListener(); |
45 | | - RJLexer lexer = new RJLexer(input); |
46 | | - lexer.removeErrorListeners(); |
47 | | - lexer.addErrorListener(err); |
48 | | - |
49 | | - CommonTokenStream tokens = new CommonTokenStream(lexer); |
50 | | - RJParser parser = new RJParser(tokens); |
51 | | - parser.setBuildParseTree(true); |
52 | | - parser.removeErrorListeners(); |
53 | | - parser.addErrorListener(err); |
54 | | - |
55 | | - RuleContext rc = parser.prog(); |
56 | | - AliasVisitor av = new AliasVisitor(input); |
| 42 | + /** |
| 43 | + * Parses the alias declaration from the given string, throwing a SyntaxError if it is not valid |
| 44 | + */ |
| 45 | + public static AliasDTO parseAliasDefinition(String toParse) throws SyntaxError { |
| 46 | + String errorMessage = "Invalid alias definition, expected e.g. @RefinementAlias(\"Positive(int v) { v >= 0 }\")"; |
| 47 | + ParseTree rc = compile(toParse, errorMessage); |
| 48 | + AliasVisitor av = new AliasVisitor(); |
57 | 49 | AliasDTO alias = av.getAlias(rc); |
58 | 50 | if (alias == null) |
59 | | - throw new SyntaxError( |
60 | | - "Invalid alias definition, expected e.g. @RefinementAlias(\"Positive(int v) { v >= 0 }\")", s); |
| 51 | + throw new SyntaxError(errorMessage, toParse); |
61 | 52 | return alias; |
62 | 53 | } |
63 | 54 |
|
64 | | - private static ParseTree compile(String toParse) throws LJError { |
| 55 | + /** |
| 56 | + * Compiles the given string into a parse tree |
| 57 | + */ |
| 58 | + private static ParseTree compile(String toParse, String errorMessage) throws SyntaxError { |
65 | 59 | Optional<String> s = getErrors(toParse); |
66 | 60 | if (s.isPresent()) |
67 | | - throw new SyntaxError("Invalid refinement expression, expected a logical predicate", toParse); |
| 61 | + throw new SyntaxError(errorMessage, toParse); |
68 | 62 |
|
69 | | - CodePointCharStream input = CharStreams.fromString(toParse); |
70 | 63 | RJErrorListener err = new RJErrorListener(); |
71 | | - |
72 | | - RJLexer lexer = new RJLexer(input); |
73 | | - lexer.removeErrorListeners(); |
74 | | - lexer.addErrorListener(err); |
75 | | - |
76 | | - CommonTokenStream tokens = new CommonTokenStream(lexer); |
77 | | - |
78 | | - RJParser parser = new RJParser(tokens); |
79 | | - parser.setBuildParseTree(true); |
80 | | - parser.removeErrorListeners(); |
81 | | - parser.addErrorListener(err); |
| 64 | + RJParser parser = createParser(toParse, err); |
82 | 65 | return parser.prog(); |
83 | 66 | } |
84 | 67 |
|
85 | 68 | /** |
86 | | - * First passage to check if there are syntax errors |
87 | | - * |
88 | | - * @param toParse |
89 | | - * |
90 | | - * @return |
| 69 | + * Checks if the given string can be parsed without syntax errors, returning the error messages if any |
91 | 70 | */ |
92 | 71 | private static Optional<String> getErrors(String toParse) { |
93 | | - CodePointCharStream input = CharStreams.fromString(toParse); |
94 | 72 | RJErrorListener err = new RJErrorListener(); |
| 73 | + RJParser parser = createParser(toParse, err); |
| 74 | + parser.start(); // all consumed |
| 75 | + if (err.getErrors() > 0) |
| 76 | + return Optional.of(err.getMessages()); |
| 77 | + return Optional.empty(); |
| 78 | + } |
95 | 79 |
|
| 80 | + /** |
| 81 | + * Creates a parser for the given input string and error listener |
| 82 | + */ |
| 83 | + private static RJParser createParser(String toParse, RJErrorListener err) { |
| 84 | + CodePointCharStream input = CharStreams.fromString(toParse); |
96 | 85 | RJLexer lexer = new RJLexer(input); |
97 | 86 | lexer.removeErrorListeners(); |
98 | 87 | lexer.addErrorListener(err); |
99 | 88 |
|
100 | 89 | CommonTokenStream tokens = new CommonTokenStream(lexer); |
101 | | - |
102 | 90 | RJParser parser = new RJParser(tokens); |
103 | 91 | parser.setBuildParseTree(true); |
104 | 92 | parser.removeErrorListeners(); |
105 | 93 | parser.addErrorListener(err); |
106 | | - parser.start(); // all consumed |
107 | | - if (err.getErrors() > 0) |
108 | | - return Optional.of(err.getMessages()); |
109 | | - return Optional.empty(); |
| 94 | + return parser; |
110 | 95 | } |
111 | 96 | } |
0 commit comments