Changeset 198
- Timestamp:
- 10/27/09 10:46:12 (4 weeks ago)
- Location:
- trunk/cpp_analysis/src/xtc/lang/c4
- Files:
-
- 6 modified
-
C4Core.rats (modified) (8 diffs)
-
C4Extractor.java (modified) (22 diffs)
-
C4ParseTreePrinter.java (modified) (1 diff)
-
C4ParserState.java (modified) (2 diffs)
-
C4State.java (modified) (26 diffs)
-
CPPAnalyzer.java (modified) (318 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/cpp_analysis/src/xtc/lang/c4/C4Core.rats
r196 r198 52 52 ; 53 53 54 55 generic MacroBasedDeclaration = 56 <MacroBased2> ("__extension__":Keyword)? DeclarationSpecifiers SimpleDeclarator id:Identifier &{yyState.isFunctionMacro(toText(id))} 57 void:"(":Symbol FunctionMacroCallParametersList? void:")":Symbol 58 l:InitializedDeclaratorList? &{ yyState.isValid(l) } void:";":Symbol 59 { yyState.setRegisteredMacroId(toText(id)); } 60 @MacroBased2 61 / <MacroBased3> ("__extension__":Keyword)? DeclarationSpecifiers id:Identifier &{yyState.isFunctionMacro(toText(id))} 62 void:"(":Symbol FunctionMacroCallParametersList? void:")":Symbol l:InitializedDeclaratorList? 63 &{ yyState.isValid(l) } void:";":Symbol 64 { yyState.setRegisteredMacroId(toText(id)); } 65 @MacroBased3 66 / <MacroBased4> ("__extension__":Keyword)? id:Identifier &{yyState.isFunctionMacro(toText(id))} 67 void:"(":Symbol FunctionMacroCallParametersList? void:")":Symbol DeclarationSpecifiers? 68 (void:"=":Symbol Initializer)? void:";":Symbol 69 { yyState.setRegisteredMacroId(toText(id)); } 70 @MacroBased4 71 / <MacroBased5> ("__extension__":Keyword)? DeclarationSpecifier id:Identifier &{yyState.isFunctionMacro(toText(id))} 72 void:"(":Symbol FunctionMacroCallParametersList? void:")":Symbol void:"[":Symbol ArraySizeExpression? void:"]":Symbol 73 DeclarationSpecifiers? (void:"=":Symbol Initializer)? void:";":Symbol 74 { yyState.setRegisteredMacroId(toText(id)); } 75 @MacroBased5 76 / <MacroBased6> ("__extension__":Keyword)? DeclarationSpecifier id:Identifier &{yyState.isFunctionMacro(toText(id))} 77 void:"(":Symbol FunctionMacroCallParametersList? void:")":Symbol DeclarationSpecifiers? 78 (void:"=":Symbol Initializer)? void:";":Symbol 79 { yyState.setRegisteredMacroId(toText(id)); } 80 @MacroBased6 81 / <MacroBased7> ("__extension__":Keyword)? DeclarationSpecifier DeclarationSpecifier id:Identifier &{yyState.isFunctionMacro(toText(id))} 82 void:"(":Symbol FunctionMacroCallParametersList? void:")":Symbol 83 DeclarationSpecifiers? (void:"=":Symbol Initializer)? void:";":Symbol 84 { yyState.setRegisteredMacroId(toText(id)); } 85 @MacroBased7 86 / <MacroBased8> ("__extension__":Keyword)? DeclarationSpecifier DeclarationSpecifier id:Identifier &{yyState.isFunctionMacro(toText(id))} 87 DeclarationSpecifiers? (void:"=":Symbol Initializer)? void:";":Symbol 88 { yyState.setRegisteredMacroId(toText(id)); } 89 @MacroBased8 90 / <MacroBased9> ("__extension__":Keyword)? DeclarationSpecifier MacroFunctionExpressionWrapper void:";":Symbol 91 @MacroBased9 92 / <MacroBased10> ("__extension__":Keyword)? DeclarationSpecifier void:"*":Symbol id:Identifier &{yyState.isFunctionMacro(toText(id))} 93 void:"(":Symbol FunctionMacroCallParametersList? void:")":Symbol DeclarationSpecifiers? (void:"=":Symbol Initializer)? void:";":Symbol 94 { yyState.setRegisteredMacroId(toText(id)); } 95 @MacroBased10 96 ; 97 98 54 99 generic Declaration := 55 <MacroBased2> k:("__extension__":Keyword)? d:DeclarationSpecifiers sId:SimpleDeclarator id:Identifier &{yyState.isFunctionMacro(toText(id))} 56 void:"(":Symbol f:FunctionMacroCallParametersList? void:")":Symbol 57 l:InitializedDeclaratorList? &{ yyState.isValid(l) } void:";":Symbol 58 { yyValue = GNode.create("MacroBased2",k, d, sId, id, f, yyState.getMacro(toText(id))); } 59 //@MacroBased2 60 / <MacroBased3> mb3_k:("__extension__":Keyword)? mb3_ds:DeclarationSpecifiers id:Identifier &{yyState.isFunctionMacro(toText(id))} 61 void:"(":Symbol f:FunctionMacroCallParametersList? void:")":Symbol l:InitializedDeclaratorList? 62 &{ yyState.isValid(l) } void:";":Symbol 63 { yyValue = yyState.annotate(GNode.create("MacroBased3", mb3_k, mb3_ds, id, f, l, yyState.getMacro(toText(id)))); } 64 //@MacroBased3 65 / <MacroBased4> k:("__extension__":Keyword)? id:Identifier &{yyState.isFunctionMacro(toText(id))} 66 void:"(":Symbol f:FunctionMacroCallParametersList? void:")":Symbol d:DeclarationSpecifiers? 67 init:(void:"=":Symbol Initializer)? void:";":Symbol 68 { yyValue = yyState.annotate(GNode.create("MacroBased4",k, id, f, d, init, yyState.getMacro(toText(id)))); } 69 //@MacroBased4 {System.out.println("TEST");} 70 / <MacroBased5> mb5_k:("__extension__":Keyword)? mb5_ds:DeclarationSpecifier id:Identifier &{yyState.isFunctionMacro(toText(id))} 71 void:"(":Symbol f:FunctionMacroCallParametersList? void:")":Symbol void:"[":Symbol as:ArraySizeExpression? void:"]":Symbol 72 mb5_ds2:DeclarationSpecifiers? init:(void:"=":Symbol Initializer)? void:";":Symbol 73 { yyValue = yyState.annotate(GNode.create("MacroBased5", mb5_ds, id, f, as, mb5_ds2, init, yyState.getMacro(toText(id)))); } 74 //@MacroBased5 75 / <MacroBased6> mb6_k:("__extension__":Keyword)? d:DeclarationSpecifier id:Identifier &{yyState.isFunctionMacro(toText(id))} 76 void:"(":Symbol f:FunctionMacroCallParametersList? void:")":Symbol ds:DeclarationSpecifiers? 77 init:(void:"=":Symbol Initializer)? void:";":Symbol 78 { yyValue = GNode.create("MacroBased6",mb6_k, d, id, f, ds, init, yyState.getMacro(toText(id))); } 79 //@MacroBased6 80 / <MacroBased7> mb7_k:("__extension__":Keyword)? ds1:DeclarationSpecifier ds2:DeclarationSpecifier id:Identifier &{yyState.isFunctionMacro(toText(id))} 81 void:"(":Symbol f:FunctionMacroCallParametersList? void:")":Symbol 82 ds3:DeclarationSpecifiers? init:(void:"=":Symbol Initializer)? void:";":Symbol 83 { yyValue = yyState.annotate(GNode.create("MacroBased7",mb7_k, ds1, ds2, id, f, ds3, init, yyState.getMacro(toText(id)))); } 84 //@MacroBased7 85 / <MacroBased8> mb8_k:("__extension__":Keyword)? mb8_ds1:DeclarationSpecifier mb8_ds2:DeclarationSpecifier id:Identifier &{yyState.isFunctionMacro(toText(id))} 86 ds3:DeclarationSpecifiers? init:(void:"=":Symbol Initializer)? void:";":Symbol 87 { yyValue = yyState.annotate(GNode.create("MacroBased8",mb8_k, mb8_ds1, mb8_ds2, id, ds3, init, yyState.getMacro(toText(id)))); } 88 //@MacroBased8 89 / <MacroBased9> ("__extension__":Keyword)? DeclarationSpecifier MacroFunctionExpression void:";":Symbol 90 @MacroBased9 91 / <MacroBased10> k:("__extension__":Keyword)? ds1:DeclarationSpecifier void:"*":Symbol id:Identifier &{yyState.isFunctionMacro(toText(id))} 92 void:"(":Symbol f:FunctionMacroCallParametersList? void:")":Symbol ds2:DeclarationSpecifiers? init:(void:"=":Symbol Initializer)? void:";":Symbol 93 { yyValue = yyState.annotate(GNode.create("MacroBased10",k, ds1, id, f, ds2, init, yyState.getMacro(toText(id)))); } 94 //@MacroBased10 100 <MacroBased> macroBased:MacroBasedDeclaration 101 { yyValue = yyState.annotate(GNode.create("MacroBasedDeclaration", macroBased, yyState.getMacro(yyState.getRegisteredMacroId())));} 95 102 / <RegularWithIfSection> ("__extension__":Keyword)? DeclarationSpecifiers AttributeSpecifierList? 96 103 Declarator SimpleAssemblyExpression? AttributeSpecifierList? void:"=":Symbol IfSection … … 130 137 Node StructureDeclarator += 131 138 <Simple> ... 132 / <MacroCall> MacroFunctionExpression 139 / <MacroCall> MacroFunctionExpressionWrapper 133 140 ; 134 141 … … 155 162 generic Define = 156 163 <FunctionMacro> fm:FunctionMacro { if(yyState.isDefined()) yyState.storeMacro(fm); } 157 / <ObjectMacro> om:ObjectMacro { if(yyState.isDefined() ) yyState.storeMacro(om); }164 / <ObjectMacro> om:ObjectMacro { if(yyState.isDefined()) yyState.storeMacro(om); } 158 165 / <Undef> un:Undef 159 166 ; … … 237 244 {yyState.setAttribute();} 238 245 / <Declaration> Declaration 239 / <MacroFunctionCallExpression> MacroFunctionExpression //An object macro is defined according to another function macro246 / <MacroFunctionCallExpression> MacroFunctionExpressionWrapper //An object macro is defined according to another function macro 240 247 / <Expression> Expression 241 248 / <DeclarationWOColon> DeclarationWithoutColon … … 342 349 Node Statement += 343 350 <PElse> void:"else":Keyword Statement? 344 / <FuncMacroCompoundStmt> FunctionMacroCallStatement 351 / <FuncMacroCompoundStmt> funcMacroCall:FunctionMacroCallStatement 352 { yyValue = GNode.create("FunctionMacroCompoundStmt", funcMacroCall, yyState.getMacro(yyState.getRegisteredMacroId())); } 345 353 / <ObjectMacroStmt> id:Identifier &{ yyState.isMacro(toText(id)) && !(yyState.isBlockBeginning(toText(id)) || yyState.isBlockEnding(toText(id)))} 346 354 { yyValue = GNode.create("MacroReference",id,yyState.getMacro(toText(id)));} … … 393 401 id:Identifier &{yyState.isFunctionMacro(toText(id))} void:"(":Symbol f:FunctionMacroCallParametersList? 394 402 void:")":Symbol c:CompoundStatement? 395 { yy Value = GNode.create("FunctionMacroCallStatement", id, f, c, yyState.getMacro(toText(id))); }403 { yyState.setRegisteredMacroId(toText(id)); } 396 404 ; 397 405 398 406 generic MacroBasedUnaryExpression = 399 DeclarationSpecifier MacroFunctionExpression 407 DeclarationSpecifier MacroFunctionExpressionWrapper 400 408 ; 401 409 … … 415 423 / <Decrement> MacroBasedPostfixExpression void:"--":Symbol 416 424 @MPostdecrementExpression 417 / <Base> MacroFunctionExpression 418 ; 419 425 / <Base> MacroFunctionExpressionWrapper 426 ; 427 428 429 generic MacroFunctionExpressionWrapper = 430 mfexp:MacroFunctionExpression 431 { yyValue = yyState.annotate(GNode.create("MacroFunctionExpressionWrapper", mfexp, yyState.getMacro(yyState.getRegisteredMacroId()))); } 432 ; 420 433 generic MacroFunctionExpression = 421 434 id:Identifier &{yyState.isFunctionMacro(toText(id))} void:"(":Symbol f:FunctionMacroCallParametersList? 422 void:")":Symbol { yyValue = GNode.create("MacroFunctionExpression", id, f, yyState.getMacro(toText(id))); } 435 void:")":Symbol 436 { yyState.setRegisteredMacroId(toText(id));} 423 437 ; 424 438 … … 507 521 generic SimpleDeclarator := 508 522 <Declarator> id:Identifier &{!yyState.isMacro(toText(id))} {yyState.bind(toText(id)); } 509 / <FuncMacroDeclarator> l:MacroFunctionExpression 523 / <FuncMacroDeclarator> l:MacroFunctionExpressionWrapper 510 524 / <ObjMacroDeclarator> id:Identifier &{yyState.isFunctionMacro(toText(id))} {yyState.bind(toText(id));} //a FunctionMacro name used as a regular identifier 511 525 / <another> id:Identifier &{yyState.isObjectMacroForId(toText(id))} {yyState.bind(toText(id));} -
trunk/cpp_analysis/src/xtc/lang/c4/C4Extractor.java
r196 r198 4 4 import java.io.FileNotFoundException; 5 5 import java.io.FileOutputStream; 6 import java.io.FileWriter;7 import java.io.IOException;8 6 import java.io.OutputStreamWriter; 9 7 import java.util.ArrayList; 10 8 import java.util.HashMap; 11 import java.util.Iterator;12 9 import java.util.Map; 13 import java.util.Set; 14 15 import com.sun.org.apache.bcel.internal.generic.RETURN; 10 16 11 17 12 import xtc.tree.Annotation; … … 23 18 import xtc.tree.Token; 24 19 import xtc.tree.Visitor; 25 import xtc.typical.TypicalTypes.funcRec;26 import xtc.util.Runtime;27 20 28 21 public class C4Extractor extends Visitor { … … 37 30 /** The Configuration option to extract **/ 38 31 private String configOption; 32 39 33 /** The list of nodes marked as to be extracted by the CPP Analyzer **/ 40 34 private ArrayList<C4Extractable> toExtract; … … 43 37 private Node tree; 44 38 /** The new Tree with everything extracted **/ 45 private Node newTree; 39 private Node treeExtracted; 40 /** The new Tree with woven **/ 41 private Node treeWoven; 46 42 /** The name of the top level file to be extracted **/ 47 43 /** We do not extract anything from the included header files **/ … … 52 48 private Map<String, GNode> functionDefinitions; 53 49 50 /** 51 * The list of the headers included that should be removed 52 */ 53 private ArrayList<String> headersToRemove; 54 54 55 /** The collection of functionDefinitions after all the modification 55 56 * populated during the extraction process … … 59 60 private Node father; 60 61 61 public C4Extractor(String featureName, String optExtract, ArrayList<C4Extractable> toExtract, Node unit, String fileName, Map<String, GNode> functionDefinitions ) { 62 public C4Extractor(String featureName, String optExtract, ArrayList<C4Extractable> toExtract, 63 Node unit, String fileName, Map<String, GNode> functionDefinitions, ArrayList<String> headersToRemove ) { 62 64 this.featureName = featureName; 63 65 configOption = optExtract; … … 67 69 this.functionDefinitions = functionDefinitions; 68 70 modifiedFunctionDefinitions = new HashMap<String, GNode> (); 69 } 70 71 71 this.headersToRemove = headersToRemove; 72 } 73 74 75 /** 76 * Builds a node with all the new children while keeping the Formatting 77 * @param n The original node 78 * @param newChildren A map associating an index and the object representing the associated children 79 * @return The new Formatting node with the new children 80 */ 72 81 static Node build(Formatting n, HashMap<Integer, Object> newChildren) { 73 82 Formatting result = null ; … … 105 114 } 106 115 116 /** 117 * The extraction visitor 118 * @param n The node to visit 119 * @return The modified version of the node to visit without what has been extracted 120 */ 107 121 private Node extractVisitor(Node n) { 108 //Node modified = GNode.create((GNode)n);109 110 122 //When we remove some children, we have to change the index. 111 123 //the modifiedIndex is aware of the updated size. 112 113 124 int modifiedIndex = 0; 114 ArrayList<Integer> toRemove = new ArrayList<Integer>();125 //A map of the new children 115 126 HashMap<Integer, Object> newChildren = new HashMap<Integer, Object>(); 127 116 128 String name = n.getName(); 117 129 … … 128 140 129 141 if(isToBeExtracted(child)) { 130 142 //if this child is going to be extracted 143 //we do nothing 144 131 145 if(DBG_EXTRACT) 132 146 System.out.println("We are going to remove child number : " + index); 133 147 134 father = n; 135 toRemove.add(index); 148 149 //The child must be extracted 150 //We check if this is a global introduction 151 if(isGlobalIntroduction(child)) { 152 153 //creation of the node to add to mark where we have extracted 154 GNode tmp = GNode.create("tmp", false); 155 Formatting after = Formatting.after1(tmp, new Token("//Extracted Global\n\n")); 156 //TODO we must insert something more meaningful 157 158 //We replace the original global introduction by the newly created node 159 newChildren.put(new Integer(modifiedIndex), after); 160 modifiedIndex++; 161 162 } 136 163 137 164 } else { … … 145 172 146 173 if(!dispatched.getName().equals("toPurge")) { 174 147 175 newChildren.put(new Integer(modifiedIndex), dispatched); 148 176 modifiedIndex++; 177 149 178 } else { 150 179 if(DBG_EXTRACT) … … 161 190 } else if(n.get(i) instanceof String) { 162 191 newChildren.put(new Integer(modifiedIndex), n.getString(i)); 163 164 192 modifiedIndex++; 165 193 … … 167 195 newChildren.put(new Integer(modifiedIndex), null); 168 196 modifiedIndex++; 197 169 198 } else { 170 199 newChildren.put(new Integer(modifiedIndex), n.get(i)); 171 200 modifiedIndex++; 201 172 202 } 173 203 } 174 204 175 205 if(newChildren.size() == 0) { 206 //if there's no child left, we can purge the current node 207 //TODO check what can happen because of the formatting 176 208 return GNode.create("toPurge", n); 177 209 } … … 180 212 Node modified = null; 181 213 214 //We create and populate the node that is going to be returned. 182 215 if(n instanceof GNode) { 183 216 modified = GNode.create(name, newChildren.size()); … … 192 225 //We look for the name of this function 193 226 if (functionDefinitions.containsValue(n)) { 227 //For the weaving, we collect which functions have been modified. 194 228 for (String funcName: functionDefinitions.keySet()) { 195 229 if(functionDefinitions.get(funcName) == n) { … … 221 255 } 222 256 257 258 /** 259 * Tells whether if the child which is to be extracted is a global introduction 260 * (i.e. an IfSection outside any scope). 261 * @param child The child to test if it's a global intro or not 262 * @return <code>true</code> if the child is a global 263 */ 264 private boolean isGlobalIntroduction(Node child) { 265 for(C4Extractable toBeExtracted : toExtract) { 266 if(toBeExtracted.getGNodeToExtract() == child) { 267 if(toBeExtracted.getFuncDef() == null 268 && toBeExtracted.getFuncName() == null 269 && toBeExtracted.getKind().equals("introduction")) { 270 return true; 271 } 272 else { 273 return false; 274 } 275 276 } 277 } 278 return false; 279 } 280 281 /** 282 * Visits the specified annotation 283 */ 223 284 public Object visit(Annotation a) { 224 285 return extractVisitor(a); 225 286 } 226 287 288 /** 289 * Visits the specified Node 290 */ 227 291 public Node visit(Node n) { 228 292 return extractVisitor(n); … … 230 294 231 295 public void extract() { 232 newTree= (Node) dispatch(tree);296 treeExtracted = (Node) dispatch(tree); 233 297 234 298 if(DBG_EXTRACT) { … … 238 302 console.format(tree, false).pln().flush(); 239 303 System.out.println("\n\nAFTER EXTRACTION"); 240 console.format( newTree, false).pln().flush();304 console.format(treeExtracted, false).pln().flush(); 241 305 242 306 System.out.println("\n\n###EXTRACTION RESULT#####\n"); … … 245 309 console.flush(); 246 310 System.out.println("PARSENEWTREE PRINTER\n\n"); 247 new C4ParseTreePrinter(console).dispatch( newTree);311 new C4ParseTreePrinter(console).dispatch(treeExtracted); 248 312 console.flush(); 249 313 System.out.println("\n#######\n"); … … 252 316 253 317 Printer result_file = new Printer(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("__extract_"+topLevel.substring(topLevel.lastIndexOf("/") + 1 ))))); 254 new C4ParseTreePrinter(result_file).dispatch( newTree);318 new C4ParseTreePrinter(result_file).dispatch(treeExtracted); 255 319 result_file.flush(); 256 320 … … 261 325 262 326 //Weaving 263 weave(newTree); 264 265 266 } 267 268 269 327 328 329 weave(treeExtracted); 330 331 332 } 333 334 335 336 /** 337 * Finds what should be woven inside the function whose name is given as a parameter 338 * @param funcName The name of the function for which we look up if there's anything to weave 339 * @return The list of what mus be woven inside this function 340 */ 270 341 private ArrayList<C4Extractable> lookupToWeave(String funcName) { 271 342 ArrayList<C4Extractable> toWeave = new ArrayList<C4Extractable>(); 272 343 273 344 for(C4Extractable item : toExtract) { 274 if(item.getFuncName().equals(funcName)) { 275 toWeave.add(item); 276 } 277 } 278 345 if(item.getFuncName() != null) { 346 //We can have global introductions now without function associated 347 //So funcName can be null, in this case, we do not weave so far 348 //TODO What to do for introduction 349 if(item.getFuncName().equals(funcName)) { 350 toWeave.add(item); 351 } 352 } 353 } 354 279 355 return toWeave; 280 356 } 281 357 282 358 359 /** 360 * Performs the weaving of what has been extracted. 361 * This method transforms what has been extracted as a C4 feature 362 * @param newTree 363 */ 364 @SuppressWarnings("unused") 283 365 private void weave(Node newTree) { 366 treeWoven = newTree; 284 367 Printer console = new Printer(new BufferedWriter(new OutputStreamWriter(System.out))); 285 new ParseTreePrinter(console).dispatch(tree);286 //System.out.println("\n\nBEFORE WEAVING");287 //console.format(newTree, false).pln().flush();288 289 368 290 369 new Visitor() { 370 //For a function definition we look what must be woven 291 371 public void visitFunctionDefinition(GNode n ) { 292 372 if (modifiedFunctionDefinitions.containsValue(n)) { … … 294 374 if(modifiedFunctionDefinitions.get(funcName) == n) { 295 375 ArrayList<C4Extractable> toWeave = lookupToWeave(funcName); 376 // The actual weaving consists in inserting a new compound statement 377 // representing at the beginning of the function definition 296 378 n.getGeneric(5).add(0,blockWrapping(toWeave)); 297 379 } … … 309 391 } 310 392 311 }.dispatch(newTree); 312 313 314 315 System.out.println("\nAFTER WEAVING\n\n"); 316 console.format(newTree, false).pln().flush(); 317 System.out.println("\nAfterC4ParseTree\n"); 393 }.dispatch(treeWoven); 394 395 System.out.println("#######ORIGINAL############\n"); 396 new ParseTreePrinter(console).dispatch(tree); 397 console.flush(); 398 System.out.println("#######END OF ORIGINAL############\n"); 399 400 System.out.println("#######WOVEN############\n"); 318 401 new C4ParseTreePrinter(console).dispatch(newTree); 319 402 console.flush(); 320 System.out.println("\n#######\n"); 321 322 323 } 324 403 System.out.println("###########################\n"); 404 405 406 } 407 408 /** 409 * Tells whether this node is supposed to be extracted 410 * @param n The node to test 411 * @return <code>true</code> if this is node is supposed to be extracted 412 */ 325 413 private boolean isToBeExtracted(Node n) { 414 boolean result = false; 415 416 //If the node is part of a C4Extractable 326 417 for(C4Extractable toBeExtracted : toExtract) { 327 418 if(toBeExtracted.getGNodeToExtract() == n) { 328 return true; 329 } 330 } 331 332 return false; 333 } 334 419 result = true; 420 } 421 } 422 423 //We may also extract headers if we have extracted everything related to this header 424 if(n.getName().equals("UserHeader") || n.getName().equals("SystemHeader")) { 425 for(String headerName : headersToRemove) { 426 if(headerName.endsWith(n.getString(0))) { 427 result = true; 428 break; 429 } 430 } 431 } 432 433 return result; 434 } 435 436 437 /** 438 * Wraps what has been extracted with a block 439 * @param toWeave What must be woven 440 * @return 441 */ 335 442 private Node blockWrapping(ArrayList<C4Extractable> toWeave) { 336 443 GNode tmpGNodeBefore = GNode.create("RawFeatureBefore"); 337 GNode tmpGNodeAfter = GNode.create("RawFeatureAfter");444 GNode tmpGNodeAfter = GNode.create("RawFeatureAfter"); 338 445 339 446 for(C4Extractable item: toWeave) { 340 447 //We make the distinction between before and after 341 448 if(item.getKind().equals("before")) 342 449 tmpGNodeBefore.add(item.getGNodeToExtract()); 343 450 else if(item.getKind().equals("after")) 344 451 tmpGNodeAfter.add(item.getGNodeToExtract()); 345 346 452 } 347 453 454 //We create a GNode that is going to contain the before and after blocks 348 455 GNode featureBlock = GNode.create("FeatureBlockStatement"); 349 456 -
trunk/cpp_analysis/src/xtc/lang/c4/C4ParseTreePrinter.java
r196 r198 35 35 } 36 36 37 public void visitMacroBased 4(GNode n) {37 public void visitMacroBasedDeclaration(GNode n) { 38 38 int i = 0; 39 39 for (Object o : n) { -
trunk/cpp_analysis/src/xtc/lang/c4/C4ParserState.java
r196 r198 300 300 301 301 boolean tmpCondValueSet = false; 302 303 // Logger dbgLogger; 304 305 /** 302 303 /* 304 * Variable that contains the name of the macro currently used inside a declaration 305 * only used as a temporary storage for the parser 306 */ 307 private String registeredMacroId; 308 309 /* 310 * Sets the id of the registered macro 311 * 312 */ 313 public String getRegisteredMacroId() { 314 return registeredMacroId; 315 } 316 317 public void setRegisteredMacroId(String registeredMacroId) { 318 this.registeredMacroId = registeredMacroId; 319 } 320 321 /** 306 322 * Default constructor. 307 323 */ … … 1439 1455 1440 1456 public String visitFunctionMacro(GNode functionMacro) { 1441 return (String)dispatch(functionMacro.getGeneric(2)); 1442 } 1443 1457 return (String) dispatch(functionMacro.getGeneric(2)); 1458 } 1459 1460 public String visitMacroFunctionExpressionWrapper(GNode wrapper) { 1461 return (String) dispatch(wrapper.getGeneric(0)); 1462 } 1463 1464 public void visit(GNode n) { 1465 System.out.println(n); 1466 System.out.println("Location " + n.getLocation()); 1467 System.exit(-1); 1468 } 1444 1469 1445 1470 }.dispatch(getMacro(macroFunctionName)); -
trunk/cpp_analysis/src/xtc/lang/c4/C4State.java
r193 r198 22 22 */ 23 23 public class C4State { 24 25 26 /** A parsing context. */27 protected static class Context {28 29 /** The next context. */30 public Context next;31 32 /**33 * The flags for this context. The flags from LSB to MSB are:34 * FLAG_TYPEDEF, FLAG_SCOPE, FLAG_TYPE_SPEC, FLAG_PARAMS,35 * FLAG_MODIFIED, FLAG_STRUCTURE.36 */37 public int flags;38 39 /** The bindings for this context, if any. */40 public final HashMap<String,Boolean> bindings;41 42 /** The marked annotation, if any. */43 public Annotation mark;44 45 // ------------------------------------------------------------------------46 47 /** Create a new context. */48 public Context() {49 bindings = new HashMap<String,Boolean>();50 }51 52 // ------------------------------------------------------------------------53 54 /** Clear this context. */55 public void clear() {56 if (isSet(FLAG_MODIFIED)) {57 bindings.clear();58 }59 flags = 0;60 mark = null;61 }62 63 // ------------------------------------------------------------------------64 65 /**66 * Determine whether the specified flag is set.67 *68 * @param flag The flag.69 * @return <code>true</code> if the flag is set.70 */71 public boolean isSet(final int flag) {72 return (0 != (flag & flags));73 }74 75 /**76 * Set the specified flag.77 *78 * @param flag The flag.79 */80 public void set(final int flag) {81 flags |= flag;82 }83 84 /**85 * Clear the specified flag.86 *87 * @param flag The flag.88 */89 public void clear(final int flag) {90 flags &= ~flag;91 }92 93 }94 95 // ==========================================================================96 97 /** The flag for whether to print debug information to the console. */98 protected static final boolean DEBUG = false;99 100 /** The initial size of the context pool. */101 protected static final int POOL_INIT = 10;102 103 /** The increment of the context pool. */104 protected static final int POOL_INCR = 5;105 106 /** The flag for typedefs. */107 protected static final int FLAG_TYPEDEF = 0x01;108 109 /** The flag for scopes. */110 protected static final int FLAG_SCOPE = 0x02;111 112 /** The flag for having parsed a type specifier. */113 protected static final int FLAG_TYPE_SPEC = 0x04;114 115 /** The flag for having parsed a function parameter list. */116 protected static final int FLAG_PARAMS = 0x08;117 118 /** The flag for having modified the bindings. */119 protected static final int FLAG_MODIFIED = 0x10;120 121 /** The flag for structure/union declaration lists. */122 protected static final int FLAG_STRUCTURE = 0x20;24 25 26 /** A parsing context. */ 27 protected static class Context { 28 29 /** The next context. */ 30 public Context next; 31 32 /** 33 * The flags for this context. The flags from LSB to MSB are: 34 * FLAG_TYPEDEF, FLAG_SCOPE, FLAG_TYPE_SPEC, FLAG_PARAMS, 35 * FLAG_MODIFIED, FLAG_STRUCTURE. 36 */ 37 public int flags; 38 39 /** The bindings for this context, if any. */ 40 public final HashMap<String,Boolean> bindings; 41 42 /** The marked annotation, if any. */ 43 public Annotation mark; 44 45 // ------------------------------------------------------------------------ 46 47 /** Create a new context. */ 48 public Context() { 49 bindings = new HashMap<String,Boolean>(); 50 } 51 52 // ------------------------------------------------------------------------ 53 54 /** Clear this context. */ 55 public void clear() { 56 if (isSet(FLAG_MODIFIED)) { 57 bindings.clear(); 58 } 59 flags = 0; 60 mark = null; 61 } 62 63 // ------------------------------------------------------------------------ 64 65 /** 66 * Determine whether the specified flag is set. 67 * 68 * @param flag The flag. 69 * @return <code>true</code> if the flag is set. 70 */ 71 public boolean isSet(final int flag) { 72 return (0 != (flag & flags)); 73 } 74 75 /** 76 * Set the specified flag. 77 * 78 * @param flag The flag. 79 */ 80 public void set(final int flag) { 81 flags |= flag; 82 } 83 84 /** 85 * Clear the specified flag. 86 * 87 * @param flag The flag. 88 */ 89 public void clear(final int flag) { 90 flags &= ~flag; 91 } 92 93 } 94 95 // ========================================================================== 96 97 /** The flag for whether to print debug information to the console. */ 98 protected static final boolean DEBUG = false; 99 100 /** The initial size of the context pool. */ 101 protected static final int POOL_INIT = 10; 102 103 /** The increment of the context pool. */ 104 protected static final int POOL_INCR = 5; 105 106 /** The flag for typedefs. */ 107 protected static final int FLAG_TYPEDEF = 0x01; 108 109 /** The flag for scopes. */ 110 protected static final int FLAG_SCOPE = 0x02; 111 112 /** The flag for having parsed a type specifier. */ 113 protected static final int FLAG_TYPE_SPEC = 0x04; 114 115 /** The flag for having parsed a function parameter list. */ 116 protected static final int FLAG_PARAMS = 0x08; 117 118 /** The flag for having modified the bindings. */ 119 protected static final int FLAG_MODIFIED = 0x10; 120 121 /** The flag for structure/union declaration lists. */ 122 protected static final int FLAG_STRUCTURE = 0x20; 123 123 124 124 /** The name of the current aspect in context. */ … … 137 137 138 138 public static final int FLAG_CPPSCOPE = 0x0200; 139 139 140 140 /** The level of nested include. */ 141 141 int includeLevel = 0; … … 143 143 /** An instance of the include path manager. */ 144 144 protected C4IncludePathManager includePathManager = null; 145 146 /** A flag indicating whether we are in the context of a parseTree147 */148 private boolean parseTree = false;145 146 /** A flag indicating whether we are in the context of a parseTree 147 */ 148 private boolean parseTree = false; 149 149 150 150 /** A macros manager. */ 151 151 protected C4MacrosManager macrosManager = null; 152 152 153 153 /** A list of parsed header file. */ 154 154 private List<String> parsedHeaderFiles = null; 155 155 156 156 /** A flag to tell whether we are defining a Macro 157 157 * Used to define the new line 158 158 */ 159 159 public static boolean inMacroFlag = false; 160 160 161 161 /** A flag to tell whether we are defining a Function 162 162 * Used to avoid considering Macros as DeclarationSpecifier 163 163 */ 164 public static boolean inFuncDef = false;164 public static boolean inFuncDef = false; 165 165 /** 166 166 * Store the parameters names of the currently defined function macro... … … 172 172 List<String> typeSpecifiers = null; 173 173 174 175 //==========================================================================176 177 /** The pool of parsing contexts. */178 private Context pool;179 180 /**181 * The top of the context stack. The implementation assumes that182 * this field always references at least one context, which183 * corresponds to the global namespace.184 */185 protected Context top;186 187 /** The current nesting level. */188 protected int nesting;189 190 /** The current annotation, if any. */191 protected Annotation annotation;192 193 //==========================================================================194 195 // ==========================================================================196 197 /**198 * Add the specified number of fresh contexts to the pool.199 *200 * @param n The number to add.201 */202 protected void fillPool(int n) {203 for (int i=0; i<n; i++) {204 addToPool(new Context());205 }206 }207 208 /**209 * Take a context from the pool, refilling the pool if necessary.210 *211 * @return A fresh context.212 */213 protected Context takeFromPool() {214 if (null == pool) {215 fillPool(POOL_INCR);216 }217 218 Context c = pool;219 pool = c.next;220 c.next = null;221 return c;222 }223 224 /**225 * Return the specified context to the pool, clearing it along the226 * way.227 *228 * @param c The context to return.229 */230 protected void addToPool(Context c) {231 c.next = pool;232 c.clear();233 pool = c;234 }235 236 //================================================================================237 238 /**239 * Push the specified context onto the context stack.240 *241 * @param c The context to push.242 */243 protected void push(Context c) {244 c.next = top;245 top = c;246 }247 248 /**249 * Pop a context from the context stack.250 *251 * @return The top-most context.252 */253 protected Context pop() {254 Context c = top;255 top = c.next;256 c.next = null;257 return c;258 }259 260 public void start() {261 if (DEBUG) {262 nesting++;263 System.out.println("start(" + nesting + ")");264 }265 266 push(takeFromPool());267 }268 269 public void commit() {270 if (DEBUG) {271 if (top.isSet(FLAG_SCOPE)) {272 System.out.println("implied exitScope(" + nesting + ")");273 }274 System.out.println("commit(" + nesting + ")");275 nesting--;276 }277 278 addToPool(pop());279 }280 281 public void abort() {282 if (DEBUG) {283 if (top.isSet(FLAG_SCOPE)) {284 System.out.println("implied exitScope(" + nesting + ")");285 }286 System.out.println("abort(" + nesting + ")");287 nesting--;288 }289 290 addToPool(pop());291 }292 293 // ==========================================================================294 // ==========================================================================295 296 /** Record a typedef storage class specifier. */297 public void typedef() {298 if (DEBUG)299 System.out.println("typedef()");300 top.set(FLAG_TYPEDEF);301 }302 303 /** Record a function parameter list. */304 public void parameters() {305 if (DEBUG) System.out.println("parameters()");306 top.set(FLAG_PARAMS);307 }308 309 /** Record a function declarator. */310 public void functionDeclarator() {311 if (DEBUG) System.out.println("functionDeclarator()");312 top.clear(FLAG_PARAMS);313 }314 315 /** Enter a new scope. */316 public void pushScope() {317 if (DEBUG)318 System.out.println("pushScope(" + nesting + ")");319 top.set(FLAG_SCOPE);320 }321 322 /** Exit the last scope. */323 public void popScope() {324 if (DEBUG)325 System.out.println("popScope(" + nesting + ")");326 top.clear(FLAG_SCOPE);327 }328 329 /** Enter a structure declaration list. */330 public void enterStructure() {331 if (DEBUG) System.out.println("enterStructure(" + nesting + ")");332 top.set(FLAG_STRUCTURE);333 }334 335 /** Exit a structure declaration list. */336 public void exitStructure() {337 if (DEBUG) System.out.println("exitStructure(" + nesting + ")");338 top.clear(FLAG_STRUCTURE);339 }340 341 342 343 /**344 * Determine whether a declaration actually is a declaration. This345 * method determines whether the sequence346 * <pre>347 * DeclarationSpecifiers l:InitializedDeclaratorList?348 * </pre>349 * can actually represent a declaration. It assumes that any type350 * specifier encountered while parsing351 * <code>DeclarationSpecifiers</code> has been marked through {@link352 * #typeSpecifier()}.353 *354 * @param idl The result of parsing the optional initialized355 * declarator list.356 * @return <code>true</code> if the declaration is a declaration.357 */358 public boolean isValid(Node idl) {359 return top.isSet(FLAG_TYPE_SPEC) || (null != idl);360 }361 362 // ==========================================================================363 364 //==========================================================================365 366 /**367 * Record a line marker. Note that string values for the four flags368 * are interpreted as follows: Any non-null string counts for369 * <code>true</code>, while null counts for <code>false</code>.370 *371 * @see LineMarker372 *373 * @param file The file name (without quotes).374 * @param line The line number.375 * @param isStartFile The start file flag.376 * @param isReturnToFile The return to file flag.377 * @param isSystemHeader The system header flag.378 * @param isExternC The extern C flag.379 * @param location The line marker's source location.380 */381 public void lineMarker(String file, int line, String isStartFile,382 String isReturnToFile, String isSystemHeader,383 String isExternC, Location location) {384 if (DEBUG) System.out.println("lineMarker(" + file + ": " + line + ")");385 386 int flags = 0;387 if (null != isStartFile) flags |= LineMarker.FLAG_START_FILE;388 if (null != isReturnToFile) flags |= LineMarker.FLAG_RETURN_TO_FILE;389 if (null != isSystemHeader) flags |= LineMarker.FLAG_SYSTEM_HEADER;390 if (null != isExternC) flags |= LineMarker.FLAG_EXTERN_C;391 392 LineMarker marker = new LineMarker(line, file, flags, null);393 marker.setLocation(location);394 if (null == annotation) {395 annotation = marker;396 } else {397 annotation.innerMost().setNode(marker);398 }399 }400 401 /**402 * Record a pragma.403 *404 * @see Pragma405 *406 * @param directive The actual directive.407 * @param location The pragma's source location.408 */409 public void pragma(String directive, Location location) {410 if (DEBUG) System.out.println("pragma(" + directive + ")");411 412 Pragma pragma = new Pragma(directive, null);413 pragma.setLocation(location);414 if (null == annotation) {415 annotation = pragma;416 } else {417 annotation.innerMost().setNode(pragma);418 }419 }420 421 /**422 * Record an ident directive.423 *424 * @see SourceIdentity425 *426 * @param ident The actual identity marker.427 * @param location The ident directive's source location.428 */429 public void ident(String ident, Location location) {430 if (DEBUG) System.out.println("ident(" + ident + ")");431 432 SourceIdentity identity = new SourceIdentity(ident, null);433 identity.setLocation(location);434 if (null == annotation) {435 annotation = identity;436 } else {437 annotation.innerMost().setNode(identity);438 }439 }440 441 /**442 * Mark the current annotation. This method must be called before443 * recognizing the nonterminals to be annotated. Furthermore, it444 * must be called within the context of a stateful production.445 */446 public void mark() {447 if (DEBUG) System.out.println("mark()");448 if (null == annotation) {449 top.mark = null;450 } else {451 top.mark = annotation.innerMost();452 }453 }454 455 /**456 * Annotate the specified node. If any annotations have been457 * recorded and {@link #mark() marked}, the specified node is458 * wrapped by those annotations and the outer-most annotation is459 * returned. Otherwise, the specified node is returned.460 *461 * @param node The node.462 * @return The annotated node.463 */464 public Node annotate(Node node) {465 if (DEBUG)466 System.out.println("annotate(" + node + ")");467 if (null != top.mark) {468 // Find the mark in the next closest context, if it exists.469 Annotation base = null;470 Context c = top.next;471 while (null != c) {472 if (null != c.mark) {473 base = c.mark;474 break;475 }476 c = c.next;477 }478 479 // Apply the annotations between the base and current mark to480 // the specified node, while also preserving any new481 // annotations.482 Annotation a = (Annotation)top.mark.getNode();483 top.mark.setNode(node);484 if (null == base) {485 node = annotation;486 annotation = a;487 } else {488 node = base.getNode();489 base.setNode(a);490 }491 top.mark = null;492 }493 494 // Done.495 return node;496 }497 // ==========================================================================498 174 175 //========================================================================== 176 177 /** The pool of parsing contexts. */ 178 private Context pool; 179 180 /** 181 * The top of the context stack. The implementation assumes that 182 * this field always references at least one context, which 183 * corresponds to the global namespace. 184 */ 185 protected Context top; 186 187 /** The current nesting level. */ 188 protected int nesting; 189 190 /** The current annotation, if any. */ 191 protected Annotation annotation; 192 193 //========================================================================== 194 195 // ========================================================================== 196 197 /** 198 * Add the specified number of fresh contexts to the pool. 199 * 200 * @param n The number to add. 201 */ 202 protected void fillPool(int n) { 203 for (int i=0; i<n; i++) { 204 addToPool(new Context()); 205 } 206 } 207 208 /** 209 * Take a context from the pool, refilling the pool if necessary. 210 * 211 * @return A fresh context. 212 */ 213 protected Context takeFromPool() { 214 if (null == pool) { 215 fillPool(POOL_INCR); 216 } 217 218 Context c = pool; 219 pool = c.next; 220 c.next = null; 221 return c; 222 } 223 224 /** 225 * Return the specified context to the pool, clearing it along the 226 * way. 227 * 228 * @param c The context to return. 229 */ 230 protected void addToPool(Context c) { 231 c.next = pool; 232 c.clear(); 233 pool = c; 234 } 235 236 //================================================================================ 237 238 /** 239 * Push the specified context onto the context stack. 240 * 241 * @param c The context to push. 242 */ 243 protected void push(Context c) { 244 c.next = top; 245 top = c; 246 } 247 248 /** 249 * Pop a context from the context stack. 250 * 251 * @return The top-most context. 252 */ 253 protected Context pop() { 254 Context c = top; 255 top = c.next; 256 c.next = null; 257 return c; 258 } 259 260 public void start() { 261 if (DEBUG) { 262 nesting++; 263 System.out.println("start(" + nesting + ")"); 264 } 265 266 push(takeFromPool()); 267 } 268 269 public void commit() { 270 if (DEBUG) { 271 if (top.isSet(FLAG_SCOPE)) { 272 System.out.println("implied exitScope(" + nesting + ")"); 273 } 274 System.out.println("commit(" + nesting + ")"); 275 nesting--; 276 } 277 278 addToPool(pop()); 279 } 280 281 public void abort() { 282 if (DEBUG) { 283 if (top.isSet(FLAG_SCOPE)) { 284 System.out.println("implied exitScope(" + nesting + ")"); 285 } 286 System.out.println("abort(" + nesting + ")"); 287 nesting--; 288 } 289 290 addToPool(pop()); 291 } 292 293 // ========================================================================== 294 // ========================================================================== 295 296 /** Record a typedef storage class specifier. */ 297 public void typedef() { 298 if (DEBUG) 299 System.out.println("typedef()"); 300 top.set(FLAG_TYPEDEF); 301 } 302 303 /** Record a function parameter list. */ 304 public void parameters() { 305 if (DEBUG) System.out.println("parameters()"); 306 top.set(FLAG_PARAMS); 307 } 308 309 /** Record a function declarator. */ 310 public void functionDeclarator() { 311 if (DEBUG) System.out.println("functionDeclarator()"); 312 top.clear(FLAG_PARAMS); 313 } 314 315 /** Enter a new scope. */ 316 public void pushScope() { 317 if (DEBUG) 318 System.out.println("pushScope(" + nesting + ")"); 319 top.set(FLAG_SCOPE); 320 } 321 322 /** Exit the last scope. */ 323 public void popScope() { 324 if (DEBUG) 325 System.out.println("popScope(" + nesting + ")"); 326 top.clear(FLAG_SCOPE); 327 } 328 329 /** Enter a structure declaration list. */ 330 public void enterStructure() { 331 if (DEBUG) System.out.println("enterStructure(" + nesting + ")"); 332 top.set(FLAG_STRUCTURE); 333 } 334 335 /** Exit a structure declaration list. */ 336 public void exitStructure() { 337 if (DEBUG) System.out.println("exitStructure(" + nesting + ")"); 338 top.clear(FLAG_STRUCTURE); 339 } 340 341 342 343 /** 344 * Determine whether a declaration actually is a declaration. This 345 * method determines whether the sequence 346 * <pre> 347 * DeclarationSpecifiers l:InitializedDeclaratorList? 348 * </pre> 349 * can actually represent a declaration. It assumes that any type 350 * specifier encountered while parsing 351 * <code>DeclarationSpecifiers</code> has been marked through {@link 352 * #typeSpecifier()}. 353 * 354 * @param idl The result of parsing the optional initialized 355 * declarator list. 356 * @return <code>true</code> if the declaration is a declaration. 357 */ 358 public boolean isValid(Node idl) { 359 return top.isSet(FLAG_TYPE_SPEC) || (null != idl); 360 } 361 362 // ========================================================================== 363 364 //========================================================================== 365 366 /** 367 * Record a line marker. Note that string values for the four flags 368 * are interpreted as follows: Any non-null string counts for 369 * <code>true</code>, while null counts for <code>false</code>. 370 * 371 * @see LineMarker 372 * 373 * @param file The file name (without quotes). 374 * @param line The line number. 375 * @param isStartFile The start file flag. 376 * @param isReturnToFile The return to file flag. 377 * @param isSystemHeader The system header flag. 378 * @param isExternC The extern C flag. 379 * @param location The line marker's source location. 380 */ 381 public void lineMarker(String file, int line, String isStartFile, 382 String isReturnToFile, String isSystemHeader, 383 String isExternC, Location location) { 384 if (DEBUG) System.out.println("lineMarker(" + file + ": " + line + ")"); 385 386 int flags = 0; 387 if (null != isStartFile) flags |= LineMarker.FLAG_START_FILE; 388 if (null != isReturnToFile) flags |= LineMarker.FLAG_RETURN_TO_FILE; 389 if (null != isSystemHeader) flags |= LineMarker.FLAG_SYSTEM_HEADER; 390 if (null != isExternC) flags |= LineMarker.FLAG_EXTERN_C; 391 392 LineMarker marker = new LineMarker(line, file, flags, null); 393 marker.setLocation(location); 394 if (null == annotation) { 395 annotation = marker; 396 } else { 397 annotation.innerMost().setNode(marker); 398 } 399 } 400 401 /** 402 * Record a pragma. 403 * 404 * @see Pragma 405 * 406 * @param directive The actual directive. 407 * @param location The pragma's source location. 408 */ 409 public void pragma(String directive, Location location) { 410 if (DEBUG) System.out.println("pragma(" + directive + ")"); 411 412 Pragma pragma = new Pragma(directive, null); 413 pragma.setLocation(location); 414 if (null == annotation) { 415 annotation = pragma; 416 } else { 417 annotation.innerMost().setNode(pragma); 418 } 419 } 420 421 /** 422 * Record an ident directive. 423 * 424 * @see SourceIdentity 425 * 426 * @param ident The actual identity marker. 427 * @param location The ident directive's source location. 428 */ 429 public void ident(String ident, Location location) { 430 if (DEBUG) System.out.println("ident(" + ident + ")"); 431 432 SourceIdentity identity = new SourceIdentity(ident, null); 433 identity.setLocation(location); 434 if (null == annotation) { 435 annotation = identity; 436 } else { 437 annotation.innerMost().setNode(identity); 438 } 439 } 440 441 /** 442 * Mark the current annotation. This method must be called before 443 * recognizing the nonterminals to be annotated. Furthermore, it 444 * must be called within the context of a stateful production. 445 */ 446 public void mark() { 447 if (DEBUG) System.out.println("mark()"); 448 if (null == annotation) { 449 top.mark = null; 450 } else { 451 top.mark = annotation.innerMost(); 452 } 453 } 454 455 /** 456 * Annotate the specified node. If any annotations have been 457 * recorded and {@link #mark() marked}, the specified node is 458 * wrapped by those annotations and the outer-most annotation is 459 * returned. Otherwise, the specified node is returned. 460 * 461 * @param node The node. 462 * @return The annotated node. 463 */ 464 public Node annotate(Node node) { 465 if (DEBUG) 466 System.out.println("annotate(" + node + ")"); 467 if (null != top.mark) { 468 // Find the mark in the next closest context, if it exists. 469 Annotation base = null; 470 Context c = top.next; 471 while (null != c) { 472 if (null != c.mark) { 473 base = c.mark; 474 break; 475 } 476 c = c.next; 477 } 478 479 // Apply the annotations between the base and current mark to 480 // the specified node, while also preserving any new 481 // annotations. 482 Annotation a = (Annotation)top.mark.getNode(); 483 top.mark.setNode(node); 484 if (null == base) { 485 node = annotation; 486 annotation = a; 487 } else { 488 node = base.getNode(); 489 base.setNode(a); 490 } 491 top.mark = null; 492 } 493 494 // Done. 495 return node; 496 } 497 // ========================================================================== 498 499 499 500 500 public void setIncludeLevel(int includeLevel) { … … 629 629 ArrayList<Boolean> stateIfSectionStack; 630 630 ArrayList<Boolean> stateElseStack; 631 632 631 632 633 633 /** Boolean to parse the else or not **/ 634 634 boolean elseParsing = true; … … 643 643 /**Definition for Boolean IfDefinition Expressions **/ 644 644 Boolean isLeftDefined = null ; 645 645 646 646 /** 647 647 * State to Parse or Not IfSection Body … … 650 650 651 651 private boolean inFunctionDecl = false ; 652 652 653 653 public C4State() { 654 654 655 655 fillPool(POOL_INIT); 656 top = new Context();657 reset(null);656 top = new Context(); 657 reset(null); 658 658 this.nestedBranch = new ArrayList<Boolean>(); 659 659 this.parseBranch = new ArrayList<Boolean>(); … … 664 664 this.typeSpecifiers = new ArrayList<String>(); 665 665 this.macroParameters = new ArrayList<String>(); 666 667 } 668 669 666 667 } 668 669 670 670 //--------------------------------------------------------------------------- 671 671 // Include … … 706 706 } 707 707 708 /**709 * Sets the parseTree flag710 * @param parseTree711 * A boolean712 */713 public void setParseTree(boolean parseTree) {714 this.parseTree = parseTree;715 }716 717 /**718 * Gets the parseTree flag719 * @param parseTree720 * A boolean721 */722 public boolean getParseTree() {723 return parseTree;724 }708 /** 709 * Sets the parseTree flag 710 * @param parseTree 711 * A boolean 712 */ 713 public void setParseTree(boolean parseTree) { 714 this.parseTree = parseTree; 715 } 716 717 /** 718 * Gets the parseTree flag 719 * @param parseTree 720 * A boolean 721 */ 722 public boolean getParseTree() { 723 return parseTree; 724 } 725 725 /** 726 726 * To unparse not defined Macro … … 737 737 toParse--; 738 738 } 739 739 740 740 /** 741 741 * Tells whether the endif must be parsed … … 752 752 isDefined = this.stateIfSectionStack.remove(this.stateIfSectionStack.size()-1); 753 753 } 754 755 756 754 755 756 757 757 /** 758 758 * Pushes a nested parsing … … 772 772 } 773 773 } 774 774 775 775 /** 776 776 * Pops a nested parsing … … 824 824 isDefined = this.parseBranch.remove(this.parseBranch.size()-1); 825 825 } 826 826 827 827 /** 828 828 * for the String Constant with macro parameters … … 857 857 macroParameters.add(variadicParameters.getString(i)); 858 858 } else { 859 try{860 dispatch((Node)variadicParameters.getGeneric(i));861 } catch (Exception e) {}862 }859 try{ 860 dispatch((Node)variadicParameters.getGeneric(i)); 861 } catch (Exception e) {} 862 } 863 863 } 864 864 } … … 880 880 } 881 881 882 882 883 883 /** 884 884 * Tells whether or not the token is a function Macro … … 898 898 return this.macrosManager.getObjectMacro(token); 899 899 } 900 900 901 901 902 902 /** … … 952 952 annotation = null; 953 953 } 954 954 955 955 /** 956 956 * Enters the macro context. … … 958 958 public void macro() { 959 959 if (DEBUG) System.out.println("macro()"); 960 inMacroFlag = true;960 inMacroFlag = true; 961 961 } 962 962 … … 968 968 inMacroFlag = false; 969 969 } 970 970 971 971 /** 972 972 * Enters the FunctionDefinition context. 973 973 */ 974 974 public void funcDef() { 975 inFuncDef = true;976 } 977 975 inFuncDef = true; 976 } 977 978 978 public void exitFuncDef() { 979 inFuncDef = false;980 } 981 979 inFuncDef = false; 980 } 981 982 982 public boolean inFuncDefContext() { 983 return inFuncDef;983 return inFuncDef; 984 984 } 985 985 /** … … 991 991 return inMacroFlag; 992 992 } 993 994 993 994 995 995 public boolean isMacroKeyword(String id) { 996 return macrosManager.isMacroKeyword(id, this);997 } 998 996 return macrosManager.isMacroKeyword(id, this); 997 } 998 999 999 public boolean isObjectMacroForId(String id) { 1000 return macrosManager.isObjectMacroForId(id, this);1001 } 1002 1000 return macrosManager.isObjectMacroForId(id, this); 1001 } 1002 1003 1003 /** 1004 1004 * Determine whether the specified identifier names a type. … … 1012 1012 if (DEBUG) 1013 1013 System.out.println("isType " + id + " TOP " + top + " " + top.hashCode() + " " + top.flags); 1014 1014 1015 1015 // If we have already parsed a type specifier, the identifier does 1016 1016 // not name a type. … … 1045 1045 c = top; 1046 1046 do { 1047 1047 1048 1048 while (!c.isSet(FLAG_SCOPE)) { 1049 1049 /** TODO check this **/ … … 1084 1084 } 1085 1085 1086 //--------------------------------------------------------------------------1086 //-------------------------------------------------------------------------- 1087 1087 // CPP SCoping 1088 1088 // -------------------------------------------------------------------------- … … 1090 1090 public void pushCPPScope() { 1091 1091 if (DEBUG) 1092 System.out.println("pushCPPScope(" + nesting + ")");1092 System.out.println("pushCPPScope(" + nesting + ")"); 1093 1093 top.set(FLAG_CPPSCOPE); 1094 1094 } … … 1097 1097 public void popCPPScope() { 1098 1098 if (DEBUG) 1099 System.out.println("popCPPScope(" + nesting + ")");1099 System.out.println("popCPPScope(" + nesting + ")"); 1100 1100 top.clear(FLAG_CPPSCOPE); 1101 1101 } 1102 1103 1104 1102 1103 1104 1105 1105 //============================================================================== 1106 1106 /** … … 1212 1212 } 1213 1213 1214 /**1215 * Explicitly bind the specified identifier.1216 *1217 * @param id The identifier.1218 * @param isType The flag for whether the identifier represents a1219 * type.1220 */1221 public void bind(String id, boolean isType) {1222 if (DEBUG) {1223 System.out.println("bind(" + id + ", " + isType + ')');1224 }1225 1226 // Get the top-most scope.1227 Context c = top;1228 while (! c.isSet(FLAG_SCOPE)) {1229 if(null != c.next)1214 /** 1215 * Explicitly bind the specified identifier. 1216 * 1217 * @param id The identifier. 1218 * @param isType The flag for whether the identifier represents a 1219 * type. 1220 */ 1221 public void bind(String id, boolean isType) { 1222 if (DEBUG) { 1223 System.out.println("bind(" + id + ", " + isType + ')'); 1224 } 1225 1226 // Get the top-most scope. 1227 Context c = top; 1228 while (! c.isSet(FLAG_SCOPE)) { 1229 if(null != c.next) 1230 1230 c = c.next; 1231 1231 else 1232 1232 break; 1233 }1234 1235 // Record the name.1236 if (c.bindings.containsKey(id)) {1237 if (DEBUG) {1238 System.out.println("ignoring rebinding of " + id);1239 }1240 } else {1241 c.bindings.put(id, isType ? Boolean.TRUE : Boolean.FALSE);1242 c.set(FLAG_MODIFIED);1243 }1244 }1245 1246 1233 } 1234 1235 // Record the name. 1236 if (c.bindings.containsKey(id)) { 1237 if (DEBUG) { 1238 System.out.println("ignoring rebinding of " + id); 1239 } 1240 } else { 1241 c.bindings.put(id, isType ? Boolean.TRUE : Boolean.FALSE); 1242 c.set(FLAG_MODIFIED); 1243 } 1244 } 1245 1246 1247 1247 1248 1248 -
trunk/cpp_analysis/src/xtc/lang/c4/CPPAnalyzer.java
r196 r198 97 97 98 98 /** 99 * Create a new initializer. The specified node must represent an99 * Create a new initializer. The specified node must represent an 100 100 * initializer list. 101 * 102 * @param node The node. 103 * @param type The type. 104 * @param auto The flag for automatic storage. 101 * 102 * @param node 103 * The node. 104 * @param type 105 * The type. 106 * @param auto 107 * The flag for automatic storage. 105 108 */ 106 109 public Initializer(GNode node, Type type, boolean auto) { 107 this.node = node;108 this.type = type;109 this.auto = auto;110 this.base = type.resolve();110 this.node = node; 111 this.type = type; 112 this.auto = auto; 113 this.base = type.resolve(); 111 114 switch (this.base.tag()) { 112 115 case ARRAY: 113 116 this.element = base.toArray().getType().resolve(); 114 this.top = true;115 this.size = getSize(base);117 this.top = true; 118 this.size = getSize(base); 116 119 break; 117 120 case STRUCT: 118 121 case UNION: 119 122 this.element = null; 120 this.top = false;121 this.size = getSize(base);123 this.top = false; 124 this.size = getSize(base); 122 125 break; 123 126 default: 124 127 this.element = base; 125 this.top = true;126 this.size = 1;127 } 128 this.index = -1;129 this.count = 0;130 states = new ArrayList<State>();128 this.top = true; 129 this.size = 1; 130 } 131 this.index = -1; 132 this.count = 0; 133 states = new ArrayList<State>(); 131 134 } 132 135 133 136 /** 134 * Create a new nested initializer. The specified node must 135 * represent an initializer list. Both types must have been 136 * resolved. The element type may be <code>null</code>. 137 * 138 * @param node The node. 139 * @param base The base type. 140 * @param element The element type. 141 * @param auto The flag for automatic storage. 137 * Create a new nested initializer. The specified node must represent an 138 * initializer list. Both types must have been resolved. The element 139 * type may be <code>null</code>. 140 * 141 * @param node 142 * The node. 143 * @param base 144 * The base type. 145 * @param element 146 * The element type. 147 * @param auto 148 * The flag for automatic storage. 142 149 */ 143 150 Initializer(GNode node, Type base, Type element, boolean auto) { 144 this.node = node;145 this.type = base;146 this.auto = auto;147 this.base = base;148 this.element = element;149 this.top = false;150 this.size = (base == element) ? 1 : getSize(base);151 this.index = -1;152 this.count = 0;153 states = new ArrayList<State>();151 this.node = node; 152 this.type = base; 153 this.auto = auto; 154 this.base = base; 155 this.element = element; 156 this.top = false; 157 this.size = (base == element) ? 1 : getSize(base); 158 this.index = -1; 159 this.count = 0; 160 states = new ArrayList<State>(); 154 161 } 155 162 156 163 /** 157 * Process the specified designation. This method updates the 158 * internal state to reflect the designation. 159 * 160 * @param designation The designation, which may be 161 * <code>null</code>. 162 * @return <code>false</code> if the designation contains an 163 * error. 164 * Process the specified designation. This method updates the internal 165 * state to reflect the designation. 166 * 167 * @param designation 168 * The designation, which may be <code>null</code>. 169 * @return <code>false</code> if the designation contains an error. 164 170 */ 165 171 private boolean designation(GNode designation) { … … 172 178 if (base.hasStructOrUnion()) { 173 179 // Set the element type for struct/union types. 174 element = base.toTagged().getMember((int) index).resolve();175 176 } else if ((! hasSize(type)) && 177 (0 == states.size()) &&178 top) {180 element = base.toTagged().getMember((int) index) 181 .resolve(); 182 183 } else if ((!hasSize(type)) && (0 == states.size()) 184 && top) { 179 185 // We are processing an initializer list that is not 180 186 // nested and has an incomplete array as its type. 181 187 // Therefore, we record the maximum size. 182 count = Math.max(count, index +1);188 count = Math.max(count, index + 1); 183 189 } 184 190 … … 199 205 200 206 } else { 201 // Clear the saved states. We are starting with the overall207 // Clear the saved states. We are starting with the overall 202 208 // type. 203 209 if (0 != states.size()) { 204 210 final State state = states.get(0); 205 base = state.base;211 base = state.base; 206 212 element = state.element; 207 top = state.top;208 index = state.index;209 size = state.size;213 top = state.top; 214 index = state.index; 215 size = state.size; 210 216 states.clear(); 211 217 } 212 if (base.isArray()) push(base); 218 if (base.isArray()) 219 push(base); 213 220 214 221 // Process the designators. … … 223 230 final GNode designator = GNode.cast(iter.next()); 224 231 225 if (designator.hasName("ObsoleteFieldDesignation") ||226 ".".equals(designator.getString(0))) {232 if (designator.hasName("ObsoleteFieldDesignation") 233 || ".".equals(designator.getString(0))) { 227 234 // A struct/union field. 228 if (! base.hasStructOrUnion()) {229 // runtime.error("field name not in struct or union initializer",230 // designator);235 if (!base.hasStructOrUnion()) { 236 // runtime.error("field name not in struct or union initializer", 237 // designator); 231 238 return false; 232 239 } 233 240 234 241 // Extract the field name. 235 String name = designator.hasName("ObsoleteFieldDesignation") ? 236 designator.getString(0) : designator.getGeneric(1).getString(0); 242 String name = designator 243 .hasName("ObsoleteFieldDesignation") ? designator 244 .getString(0) 245 : designator.getGeneric(1).getString(0); 237 246 238 247 // Find the field. 239 if (! lookup(name)) { 240 //runtime.error("unknown field '" + name + "' in initializer", 241 // designator); 248 if (!lookup(name)) { 249 // runtime.error("unknown field '" + name + 250 // "' in initializer", 251 // designator); 242 252 return false; 243 253 } 244 254 245 255 } else { 246 // An array index. Make sure the base type is an array. 247 if (! base.isArray()) { 248 //runtime.error("array index in non-array initializer", designator); 256 // An array index. Make sure the base type is an array. 257 if (!base.isArray()) { 258 // runtime.error("array index in non-array initializer", 259 // designator); 249 260 return false; 250 261 } 251 262 252 263 // Determine the index types. 253 final Type t1 = processExpression(designator.getGeneric(1)); 254 final Type t2 = (3 == designator.size()) ? 255 processExpression(designator.getGeneric(2)) : null; 256 257 // Make sure that the indices are constant integers. 258 if ((! c().isIntegral(t1)) || 259 ((null != t2) && (! c().isIntegral(t2)))) { 260 //runtime.error("array index in initializer not of integer type", 261 // designator); 262 return false; 263 264 } else if ((! t1.hasConstant()) || 265 ((null != t2) && (! t2.hasConstant()))) { 266 //runtime.error("nonconstant array index in initializer", 267 // designator); 268 return false; 269 270 } 271 272 // Make sure that the indices are neither too small nor 273 // too large and that the range is not empty. 274 final BigInteger i1 = t1.getConstant().bigIntValue(); 275 final BigInteger i2 = 276 (null == t2) ? null : t2.getConstant().bigIntValue(); 277 278 // Test: i1 < 0, i2 < 0 279 if ((i1.compareTo(BigInteger.ZERO) < 0) || 280 ((null != i2) && (i2.compareTo(BigInteger.ZERO) < 0))) { 281 //runtime.error("negative array index in initializer", 282 // designator); 283 return false; 284 285 // Test: i1 > ARRAY_MAX, i2 > ARRAY_MAX 286 } else if ((i1.compareTo(Limits.ARRAY_MAX) > 0) || 287 ((null != i2) && (i2.compareTo(Limits.ARRAY_MAX) > 0))) { 288 //runtime.error("array index in initializer is too large", 289 // designator); 290 return false; 291 292 // Test: i2 < i1 293 } else if ((null != i2) && (i2.compareTo(i1) < 0)) { 294 //runtime.error("empty index range in initializer", designator); 295 return false; 296 297 } 298 299 // Make sure that the array index is within the array 300 // bounds. 301 final long max = (null == i2) ? i1.longValue() : i2.longValue(); 302 if ((-1 < size) && (max >= size)) { 303 //runtime.error("array index in initializer exceeds array bounds", 304 // designator); 305 return false; 306 } 307 308 if ((! hasSize(type)) && (0 == states.size()) && top) { 309 // We are processing an initializer list that is not 310 // nested and has an incomplete array as its type. 311 // Therefore, we record the maximum size. 312 count = Math.max(count, max+1); 313 } 314 315 // Update the current index. 316 index = max; 264 final Type t1 = processExpression(designator 265 .getGeneric(1)); 266 final Type t2 = (3 == designator.size()) ? processExpression(designator 267 .getGeneric(2)) 268 : null; 269 270 // Make sure that the indices are constant integers. 271 if ((!c().isIntegral(t1)) 272 || ((null != t2) && (!c().isIntegral(t2)))) { 273 // runtime.error("array index in initializer not of integer type", 274 // designator); 275 return false; 276 277 } else if ((!t1.hasConstant()) 278 || ((null != t2) && (!t2.hasConstant()))) { 279 // runtime.error("nonconstant array index in initializer", 280 // designator); 281 return false; 282 283 } 284 285 // Make sure that the indices are neither too small nor 286 // too large and that the range is not empty. 287 final BigInteger i1 = t1.getConstant().bigIntValue(); 288 final BigInteger i2 = (null == t2) ? null : t2 289 .getConstant().bigIntValue(); 290 291 // Test: i1 < 0, i2 < 0 292 if ((i1.compareTo(BigInteger.ZERO) < 0) 293 || ((null != i2) && (i2 294 .compareTo(BigInteger.ZERO) < 0))) { 295 // runtime.error("negative array index in initializer", 296 // designator); 297 return false; 298 299 // Test: i1 > ARRAY_MAX, i2 > ARRAY_MAX 300 } else if ((i1.compareTo(Limits.ARRAY_MAX) > 0) 301 || ((null != i2) && (i2 302 .compareTo(Limits.ARRAY_MAX) > 0))) { 303 // runtime.error("array index in initializer is too large", 304 // designator); 305 return false; 306 307 // Test: i2 < i1 308 } else if ((null != i2) && (i2.compareTo(i1) < 0)) { 309 // runtime.error("empty index range in initializer", 310 // designator); 311 return false; 312 313 } 314 315 // Make sure that the array index is within the array 316 // bounds. 317 final long max = (null == i2) ? i1.longValue() : i2 318 .longValue(); 319 if ((-1 < size) && (max >= size)) { 320 // runtime.error("array index in initializer exceeds array bounds", 321 // designator); 322 return false; 323 } 324 325 if ((!hasSize(type)) && (0 == states.size()) && top) { 326 // We are processing an initializer list that is not 327 // nested and has an incomplete array as its type. 328 // Therefore, we record the maximum size. 329 count = Math.max(count, max + 1); 330 } 331 332 // Update the current index. 333 index = max; 317 334 } 318 335 319 336 // Prepare for the next designator. 320 if (iter.hasNext()) push(element); 337 if (iter.hasNext()) 338 push(element); 321 339 } 322 340 … … 327 345 328 346 /** 329 * Get the result type. If this initializer list is not nested330 * an d has an incomplete array as its type, this method patches331 * the array's size.Otherwise, it returns the overall type.332 * 347 * Get the result type. If this initializer list is not nested and has 348 * an incomplete array as its type, this method patches the array's 349 * size. Otherwise, it returns the overall type. 350 * 333 351 * @return The result type. 334 352 */ 335 353 private Type getResult() { 336 if ((! hasSize(type)) &&337 (((0 == states.size()) && top) ||338 ((0 < states.size()) && states.get(0).top))) {354 if ((!hasSize(type)) 355 && (((0 == states.size()) && top) || ((0 < states.size()) && states 356 .get(0).top))) { 339 357 type = type.copy(); 340 358 type.resolve().toArray().setLength(count); … … 344 362 345 363 /** 346 * Determine the size of the specified type. For scalars, this347 * method returns 1. For unions, this method returns 1 if the348 * union has any accessible members and 0 otherwise. For structs,349 * th is method returns the number of accessible members. For350 * arrays, it returns the size if known and -1 otherwise. This351 * method is effectively static.352 * 353 * @param typeThe type.364 * Determine the size of the specified type. For scalars, this method 365 * returns 1. For unions, this method returns 1 if the union has any 366 * accessible members and 0 otherwise. For structs, this method returns 367 * the number of accessible members. For arrays, it returns the size if 368 * known and -1 otherwise. This method is effectively static. 369 * 370 * @param type 371 * The type. 354 372 * @return The type's size. 355 373 */ … … 368 386 369 387 /** 370 * Determine whether the specified type has a size. Only arrays371 * without a length do not have a size. This method is372 * effectively static.373 * 374 * @param typeThe type.388 * Determine whether the specified type has a size. Only arrays without 389 * a length do not have a size. This method is effectively static. 390 * 391 * @param type 392 * The type. 375 393 * @return <code>true</code> if the type has a size. 376 394 */ 377 395 private boolean hasSize(Type type) { 378 return (! type.hasTag(Tag.ARRAY)) ||379 type.resolve().toArray().hasLength();396 return (!type.hasTag(Tag.ARRAY)) 397 || type.resolve().toArray().hasLength(); 380 398 } 381 399 382 400 /** 383 * Look up the specified field. The current base type must be a384 * structor union type.385 * 401 * Look up the specified field. The current base type must be a struct 402 * or union type. 403 * 386 404 * @return <code>true</code> if the field was found. 387 405 */ … … 399 417 } 400 418 401 } else if (! member.hasWidth()) {419 } else if (!member.hasWidth()) { 402 420 index++; 403 421 element = member.resolve(); 404 422 push(element); 405 423 406 if (lookup(name)) return true; 424 if (lookup(name)) 425 return true; 407 426 408 427 pop(); … … 415 434 } 416 435 417 418 436 return false; 419 437 } … … 422 440 private void pop() { 423 441 // DEBUG: Pop. 424 if (1 <= DEBUG) runtime.console().indent().pln("pop").flush(); 442 if (1 <= DEBUG) 443 runtime.console().indent().pln("pop").flush(); 425 444 426 445 assert 0 != states.size() : "Empty initializer type stack"; 427 446 428 final State state = states.remove(states.size() -1);429 base = state.base;447 final State state = states.remove(states.size() - 1); 448 base = state.base; 430 449 element = state.element; 431 top = state.top;432 index = state.index;433 size = state.size;450 top = state.top; 451 index = state.index; 452 size = state.size; 434 453 } 435 454 436 455 /** 437 * Process the initializer. This method processes this 438 * initializer, reporting any errors and returning the processed 439 * type. The processed type generally is the same as the type 440 * provided to this class' constructor. However, if this 441 * intializer's type is a top-level incomplete array, it is 442 * updated with the actual size. 443 * 456 * Process the initializer. This method processes this initializer, 457 * reporting any errors and returning the processed type. The processed 458 * type generally is the same as the type provided to this class' 459 * constructor. However, if this intializer's type is a top-level 460 * incomplete array, it is updated with the actual size. 461 * 444 462 * @return The processed type. 445 463 */ … … 454 472 for (int cursor = 0; cursor < num; cursor++) { 455 473 // Get the entry and its children. 456 final GNode entry = node.getGeneric(cursor);457 // LB to avoid null pointer Exception458 // Because of the ONE rule in the parser459 // TODO check the ONE RULE460 if (entry.size() == 1)474 final GNode entry = node.getGeneric(cursor); 475 // LB to avoid null pointer Exception 476 // Because of the ONE rule in the parser 477 // TODO check the ONE RULE 478 if (entry.size() == 1) 461 479 return ErrorT.TYPE; 462 //LB 463 480 // LB 464 481 465 482 final GNode designation = entry.getGeneric(0); … … 467 484 468 485 // Process the designation. 469 if (! designation(designation)) {486 if (!designation(designation)) { 470 487 // DEBUG: Close brace. 471 if (1 <= DEBUG) runtime.console().decr().indent().pln("};").flush(); 488 if (1 <= DEBUG) 489 runtime.console().decr().indent().pln("};").flush(); 472 490 return getResult(); 473 491 } … … 477 495 // DEBUG: Print the designation. 478 496 if (1 <= DEBUG) { 479 runtime.console().indent().p(toString()).p(" = ").flush(); 480 } 481 482 if(element != null) { 497 runtime.console().indent().p(toString()).p(" = ") 498 .flush(); 499 } 500 501 if (element != null) { 483 502
