1 22 23 package net.percederberg.grammatica.output; 24 25 import java.io.IOException ; 26 27 import net.percederberg.grammatica.code.visualbasic.VisualBasicClass; 28 import net.percederberg.grammatica.code.visualbasic.VisualBasicComment; 29 import net.percederberg.grammatica.code.visualbasic.VisualBasicFile; 30 import net.percederberg.grammatica.code.visualbasic.VisualBasicImports; 31 import net.percederberg.grammatica.code.visualbasic.VisualBasicMethod; 32 import net.percederberg.grammatica.code.visualbasic.VisualBasicNamespace; 33 34 import net.percederberg.grammatica.parser.ProductionPattern; 35 import net.percederberg.grammatica.parser.TokenPattern; 36 37 47 class VisualBasicAnalyzerFile { 48 49 52 private static final String TYPE_COMMENT = 53 "<remarks>A class providing callback methods for the\n" + 54 "parser.</remarks>"; 55 56 59 private static final String ENTER_COMMENT = 60 "<summary>Called when entering a parse tree node.</summary>\n\n" + 61 "<param name='node'>the node being entered</param>\n\n" + 62 "<exception cref='ParseException'>if the node analysis\n" + 63 "discovered errors</exception>"; 64 65 68 private static final String EXIT_COMMENT = 69 "<summary>Called when exiting a parse tree node.</summary>\n\n" + 70 "<param name='node'>the node being exited</param>\n\n" + 71 "<returns>the node to add to the parse tree, or\n" + 72 " null if no parse tree should be created</returns>\n\n" + 73 "<exception cref='ParseException'>if the node analysis\n" + 74 "discovered errors</exception>"; 75 76 79 private static final String CHILD_COMMENT = 80 "<summary>Called when adding a child to a parse tree\n" + 81 "node.</summary>\n\n" + 82 "<param name='node'>the parent node</param>\n" + 83 "<param name='child'>the child node, or null</param>\n\n" + 84 "<exception cref='ParseException'>if the node analysis\n" + 85 "discovered errors</exception>"; 86 87 90 private VisualBasicParserGenerator gen; 91 92 95 private VisualBasicFile file; 96 97 100 private VisualBasicClass cls; 101 102 105 private VisualBasicMethod enter; 106 107 110 private VisualBasicMethod exit; 111 112 115 private VisualBasicMethod child; 116 117 122 public VisualBasicAnalyzerFile(VisualBasicParserGenerator gen) { 123 String name = gen.getBaseName() + "Analyzer"; 124 int modifiers; 125 126 this.gen = gen; 127 this.file = new VisualBasicFile(gen.getBaseDir(), name); 128 modifiers = VisualBasicClass.MUST_INHERIT; 129 if (gen.getPublicAccess()) { 130 modifiers += VisualBasicClass.PUBLIC; 131 } else { 132 modifiers += VisualBasicClass.FRIEND; 133 } 134 this.cls = new VisualBasicClass(modifiers, name, "Analyzer"); 135 modifiers = VisualBasicMethod.PUBLIC + VisualBasicMethod.OVERRIDES; 136 this.enter = new VisualBasicMethod(modifiers, 137 "Enter", 138 "ByVal node As Node", 139 ""); 140 this.exit = new VisualBasicMethod(modifiers, 141 "[Exit]", 142 "ByVal node As Node", 143 "Node"); 144 this.child = new VisualBasicMethod(modifiers, 145 "Child", 146 "ByVal node As Production, " + 147 "ByVal child As Node", 148 ""); 149 initializeCode(); 150 } 151 152 155 private void initializeCode() { 156 VisualBasicNamespace n; 157 String str; 158 159 file.addImports(new VisualBasicImports("PerCederberg.Grammatica.Runtime")); 161 162 if (gen.getNamespace() == null) { 164 file.addClass(cls); 165 } else { 166 n = new VisualBasicNamespace(gen.getNamespace()); 167 n.addClass(cls); 168 file.addNamespace(n); 169 } 170 171 str = file.toString() + "\n\n" + gen.getFileComment(); 173 file.addComment(new VisualBasicComment(VisualBasicComment.SINGLELINE, 174 str)); 175 176 cls.addComment(new VisualBasicComment(TYPE_COMMENT)); 178 179 enter.addComment(new VisualBasicComment(ENTER_COMMENT)); 181 enter.addCode("Select Case node.Id"); 182 cls.addMethod(enter); 183 184 exit.addComment(new VisualBasicComment(EXIT_COMMENT)); 186 exit.addCode("Select Case node.Id"); 187 cls.addMethod(exit); 188 189 child.addComment(new VisualBasicComment(CHILD_COMMENT)); 191 child.addCode("Select Case node.Id"); 192 cls.addMethod(child); 193 } 194 195 201 public void addToken(TokenPattern pattern, 202 VisualBasicConstantsFile constants) { 203 204 String constant = constants.getConstant(pattern.getId()); 205 String name; 206 207 if (!pattern.isIgnore()) { 208 name = gen.getCodeStyle().getMixedCase(pattern.getName(), true); 209 addEnterCase(constant, name, "Token"); 210 addEnterMethod(name, "Token"); 211 addExitCase(constant, name, "Token"); 212 addExitMethod(name, "Token"); 213 } 214 } 215 216 222 public void addProduction(ProductionPattern pattern, 223 VisualBasicConstantsFile constants) { 224 225 String constant = constants.getConstant(pattern.getId()); 226 String name; 227 228 if (!pattern.isSynthetic()) { 229 name = gen.getCodeStyle().getMixedCase(pattern.getName(), 230 true); 231 addEnterCase(constant, name, "Production"); 232 addEnterMethod(name, "Production"); 233 addExitCase(constant, name, "Production"); 234 addExitMethod(name, "Production"); 235 addChildCase(constant, name); 236 addChildMethod(name); 237 } 238 } 239 240 247 private void addEnterCase(String constant, String name, String type) { 248 enter.addCode("Case " + constant ); 249 enter.addCode(" Enter" + name + "(CType(node," + type + "))"); 250 enter.addCode(""); 251 } 252 253 260 private void addExitCase(String constant, String name, String type) { 261 exit.addCode("Case " + constant ); 262 exit.addCode(" return Exit" + name + "(CType(node," + type + "))"); 263 exit.addCode(""); 264 } 265 266 272 private void addChildCase(String constant, String name) { 273 child.addCode("Case " + constant ); 274 child.addCode(" Child" + name + "(node, child)"); 275 child.addCode(""); 276 } 277 278 284 private void addEnterMethod(String name, String type) { 285 VisualBasicMethod m; 286 287 m = new VisualBasicMethod(VisualBasicMethod.PUBLIC + 288 VisualBasicMethod.OVERRIDABLE, 289 "Enter" + name, 290 "ByVal node As " + type, 291 ""); 292 m.addComment(new VisualBasicComment(ENTER_COMMENT)); 293 cls.addMethod(m); 294 } 295 296 302 private void addExitMethod(String name, String type) { 303 VisualBasicMethod m; 304 305 m = new VisualBasicMethod(VisualBasicMethod.PUBLIC + 306 VisualBasicMethod.OVERRIDABLE, 307 "Exit" + name, 308 "ByVal node As " + type, 309 "Node"); 310 m.addComment(new VisualBasicComment(EXIT_COMMENT)); 311 m.addCode("Return node"); 312 cls.addMethod(m); 313 } 314 315 320 private void addChildMethod(String name) { 321 VisualBasicMethod m; 322 323 m = new VisualBasicMethod(VisualBasicMethod.PUBLIC + 324 VisualBasicMethod.OVERRIDABLE, 325 "Child" + name, 326 "ByVal node As Production, " + 327 "ByVal child As Node", 328 ""); 329 m.addComment(new VisualBasicComment(CHILD_COMMENT)); 330 m.addCode("node.AddChild(child)"); 331 cls.addMethod(m); 332 } 333 334 340 public void writeCode() throws IOException { 341 enter.addCode("End Select"); 342 exit.addCode("End Select"); 343 exit.addCode("Return node"); 344 child.addCode("End Select"); 345 file.writeCode(gen.getCodeStyle()); 346 } 347 } 348 | Popular Tags |