├── LICENSE ├── README.md ├── code-analyzer.js ├── code-generator.js ├── codegen-utils.js ├── grammar ├── build.sh ├── cpp.jison ├── cpp.jisonlex ├── cpp.js ├── jisonOutput.txt └── test.cpp ├── main.js ├── menus └── menu.json ├── package.json └── preferences └── preference.json /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 StarUML 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C++ Extension for StarUML 2 | 3 | This extension for StarUML(http://staruml.io) support to generate C++ code from UML model and to reverse C++ code to UML model. Install this extension from Extension Manager of StarUML. 4 | 5 | > :warning: This extensions do not provide perfect reverse engineering which is a test and temporal feature. If you need a complete reverse engineering feature, please check other professional reverse engineering tools. 6 | 7 | ### UMLPackage 8 | 9 | - converted to folder. 10 | 11 | ### UMLClass 12 | 13 | - converted to _Cpp Class_. (as a separate `.h` file) 14 | - `visibility` to one of modifiers `public`, `protected`, `private`. If visibility is not setted, consider as `protected`. 15 | - `isFinalSpecialization` and `isLeaf` property to `final` modifier. 16 | - Default constructor is generated. 17 | - All contained types (_UMLClass_, _UMLInterface_, _UMLEnumeration_) are generated as inner type definition. 18 | - TemplateParameter to _Cpp Template_. 19 | 20 | ### UMLAttribute 21 | 22 | - converted to _Cpp Field_. 23 | - `visibility` property to one of modifiers `public`, `protected`, `private`. If visibility is not setted, consider as `protected`. 24 | - `name` property to field identifier. 25 | - `type` property to field type. 26 | - `multiplicity` property to vector type. 27 | - `isStatic` property to `static` modifier. 28 | - `isLeaf` property to `final` modifier. 29 | - `defaultValue` property to initial value. 30 | - Documentation property to JavaDoc comment. 31 | 32 | ### UMLOperation 33 | 34 | - converted to _Cpp Methods_. 35 | - `visibility` to one of modifiers `public`, `protected`, `private`. If visibility is not setted, consider as `protected`. 36 | - `name` property to method identifier. 37 | - `isAbstract` property to `virtual` modifier. (TODO need options to create pure-virtual function or virtual function) 38 | - `isStatic` property to `static` modifier. 39 | - _UMLParameter_ to _Cpp Method Parameters_. 40 | - _UMLParameter_'s name property to parameter identifier. 41 | - _UMLParameter_'s type property to type of parameter. 42 | - _UMLParameter_ with `direction` = `return` to return type of method. When no return parameter, `void` is used. 43 | - _UMLParameter_ with `isReadOnly` = `true` to `const` modifier of parameter. 44 | 45 | ### UMLInterface 46 | 47 | - converted to _Cpp Class_. (as a separate `.h` file) 48 | - `visibility` property to one of modifiers `public`, `protected`, `private`. If visibility is not setted, consider as `protected`. 49 | - all method will treated as pure virtaul. 50 | 51 | ### UMLEnumeration 52 | 53 | | Weekdays | 54 | | -------- | 55 | | Monday | 56 | | Tuesday | 57 | | Saturday | 58 | 59 | converts 60 | 61 | ```c 62 | /* Test header @ toori67 63 | * This is Test 64 | * also test 65 | * also test again 66 | */ 67 | #ifndef (_WEEKDAYS_H) 68 | #define _WEEKDAYS_H 69 | 70 | enum Weekdays { Monday,Tuesday,Saturday }; 71 | 72 | #endif //_WEEKDAYS_H 73 | ``` 74 | 75 | - converted to _Cpp Enum_. (as a separate `.h` file) 76 | - `visibility` property to one of modifiers `public`, `protected`, `private`. If visibility is not setted, consider as `protected`. 77 | - _UMLEnumerationLiteral_ to literals of enum. 78 | 79 | ### UMLAssociationEnd 80 | 81 | - converted to _Cpp Field_. 82 | - `visibility` property to one of modifiers `public`, `protected`, `private`. If visibility is not setted, consider as `protected`. 83 | - `name` property to field identifier. 84 | - `type` property to field type. 85 | - If `multiplicity` is one of `0..*`, `1..*`, `*`, then collection type (`std::vector` ) is used. 86 | - `defaultValue` property to initial value. 87 | 88 | ### UMLGeneralization & UMLInterfaceRealization 89 | 90 | - converted to _Cpp Inheritance_ (`:`). 91 | - Allowed for _UMLClass_ to _UMLClass_, and _UMLClass_ to _UMLInterface_. 92 | 93 | ## C++ Reverse Engineering 94 | 95 | 1. Click the menu (`Tools > C++ > Reverse Code...`) 96 | 2. Select a folder containing C++ source files to be converted to UML model elements. 97 | 3. `CppReverse` model will be created in the Project. 98 | 99 | Belows are the rules to convert from C++ source code to UML model elements. 100 | 101 | ### C++ Namespace 102 | 103 | - converted to _UMLPackage_. 104 | 105 | ### C++ Class 106 | 107 | - converted to _UMLClass_. 108 | - Class name to `name` property. 109 | - Type parameters to _UMLTemplateParameter_. 110 | - Access modifier `public`, `protected` and `private` to `visibility` property. 111 | - `abstract` modifier to `isAbstract` property. 112 | - Constructors to _UMLOperation_ with stereotype `<>`. 113 | - All contained types (_UMLClass_, _UMLInterface_, _UMLEnumeration_) are generated as inner type definition. 114 | 115 | ### C++ Field (to UMLAttribute) 116 | 117 | - converted to _UMLAttribute_ if **"Use Association"** is **off** in Preferences. 118 | - Field type to `type` property. 119 | 120 | - Primitive Types : `type` property has the primitive type name as string. 121 | - `T[]`(array) or its decendants: `type` property refers to `T` with multiplicity `*`. 122 | - `T` (User-Defined Types) : `type` property refers to the `T` type. 123 | - Otherwise : `type` property has the type name as string. 124 | 125 | - Access modifier `public`, `protected` and `private` to `visibility` property. 126 | - `static` modifier to `isStatic` property. 127 | - Initial value to `defaultValue` property. 128 | 129 | ### C++ Field (to UMLAssociation) 130 | 131 | - converted to (Directed) _UMLAssociation_ if **"Use Association"** is **on** in Preferences and there is a UML type element (_UMLClass_, _UMLInterface_, or _UMLEnumeration_) correspond to the field type. 132 | - Field type to `end2.reference` property. 133 | 134 | - `T[]`(array) or its decendants: `reference` property refers to `T` with multiplicity `*`. 135 | - `T` (User-Defined Types) : `reference` property refers to the `T` type. 136 | - Otherwise : converted to _UMLAttribute_, not _UMLAssociation_. 137 | 138 | - Access modifier `public`, `protected` and `private` to `visibility` property. 139 | 140 | ### C++ Method 141 | 142 | - converted to _UMLOperation_. 143 | - Type parameters to _UMLTemplateParameter_. 144 | - Access modifier `public`, `protected` and `private` to `visibility` property. 145 | - `static` modifier to `isStatic` property. 146 | - `abstract` modifier to `isAbstract` property. 147 | 148 | ### C++ Enum 149 | 150 | - converted to _UMLEnumeration_. 151 | - Enum name to `name` property. 152 | - Type parameters to _UMLTemplateParameter_. 153 | - Access modifier `public`, `protected` and `private` to `visibility` property. 154 | 155 | --- 156 | 157 | Licensed under the MIT license (see LICENSE file). 158 | -------------------------------------------------------------------------------- /code-analyzer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 MKLab. All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | * 22 | */ 23 | 24 | const fs = require("fs"); 25 | const path = require("path"); 26 | const parser = require("./grammar/cpp"); 27 | 28 | // C++ Primitive Types 29 | var cppPrimitiveTypes = [ 30 | "sbyte", 31 | "short", 32 | "ushort", 33 | "uint", 34 | "long", 35 | "ulong", 36 | "char", 37 | "float", 38 | "double", 39 | "decimal", 40 | "bool", 41 | "void", 42 | "auto", 43 | "int", 44 | "short int", 45 | "long int", 46 | "long long", 47 | "long double", 48 | "signed int", 49 | "signed char", 50 | "signed long", 51 | "signed short", 52 | "signed short int", 53 | "signed long int", 54 | "signed long long", 55 | "signed", 56 | "unsigned", 57 | "unsigned int", 58 | "unsigned char", 59 | "unsigned long", 60 | "unsigned short", 61 | "unsigned short int", 62 | "unsigned long int", 63 | "unsigned long long", 64 | ]; 65 | 66 | /** 67 | * C++ Code Analyzer 68 | */ 69 | class CppCodeAnalyzer { 70 | /** 71 | * @constructor 72 | */ 73 | constructor() { 74 | /** @member {type.UMLModel} */ 75 | this._root = new type.UMLModel(); 76 | this._root.name = "CppReverse"; 77 | 78 | /** @member {Array.} */ 79 | this._files = []; 80 | 81 | /** @member {Object} */ 82 | this._currentCompilationUnit = null; 83 | 84 | /** 85 | * @member {{classifier:type.UMLClassifier, node: Object, kind:string}} 86 | */ 87 | this._extendPendings = []; 88 | 89 | /** 90 | * @member {{classifier:type.UMLClassifier, node: Object}} 91 | */ 92 | this._implementPendings = []; 93 | 94 | /** 95 | * @member {{classifier:type.UMLClassifier, association: type.UMLAssociation, node: Object}} 96 | */ 97 | this._associationPendings = []; 98 | 99 | /** 100 | * @member {{operation:type.UMLOperation, node: Object}} 101 | */ 102 | this._throwPendings = []; 103 | 104 | /** 105 | * @member {{namespace:type.UMLModelElement, feature:type.UMLStructuralFeature, node: Object}} 106 | */ 107 | this._typedFeaturePendings = []; 108 | 109 | this._usingList = []; 110 | } 111 | 112 | /** 113 | * Add File to Reverse Engineer 114 | * @param {File} file 115 | */ 116 | addFile(file) { 117 | this._files.push(file); 118 | } 119 | 120 | /** 121 | * Analyze all files. 122 | * @param {Object} options 123 | * @return {$.Promise} 124 | */ 125 | analyze(options) { 126 | // Perform 1st Phase 127 | this.performFirstPhase(options); 128 | 129 | // Perform 2nd Phase 130 | this.performSecondPhase(options); 131 | 132 | // Load To Project 133 | var writer = new app.repository.Writer(); 134 | writer.writeObj("data", this._root); 135 | var json = writer.current.data; 136 | app.project.importFromJson(app.project.getProject(), json); 137 | 138 | // Generate Diagrams 139 | this.generateDiagrams(options); 140 | console.log("[C++] done."); 141 | } 142 | 143 | /** 144 | * Generate Diagrams (Type Hierarchy, Package Structure, Package Overview) 145 | * @param {Object} options 146 | */ 147 | generateDiagrams(options) { 148 | var baseModel = app.repository.get(this._root._id); 149 | if (options.packageStructure) { 150 | app.commands.execute( 151 | "diagram-generator:package-structure", 152 | baseModel, 153 | true, 154 | ); 155 | } 156 | if (options.typeHierarchy) { 157 | app.commands.execute("diagram-generator:type-hierarchy", baseModel, true); 158 | } 159 | if (options.packageOverview) { 160 | baseModel.traverse((elem) => { 161 | if (elem instanceof type.UMLPackage) { 162 | app.commands.execute("diagram-generator:overview", elem, true); 163 | } 164 | }); 165 | } 166 | } 167 | 168 | /** 169 | * Find Type. 170 | * 171 | * @param {type.Model} namespace 172 | * @param {string|Object} type Type name string or type node. 173 | * @param {Object} compilationUnitNode To search type with import statements. 174 | * @return {type.Model} element correspond to the type. 175 | */ 176 | _findType(namespace, type_, compilationUnitNode) { 177 | var typeName, pathName; 178 | var _type = null; 179 | 180 | typeName = type_; 181 | 182 | if (typeof typeName !== "string") { 183 | typeName = type_.name; 184 | } 185 | 186 | pathName = [typeName]; 187 | 188 | // 1. Lookdown from context 189 | if (pathName.length > 1) { 190 | _type = namespace.lookdown(pathName); 191 | } else { 192 | _type = namespace.findByName(typeName); 193 | } 194 | 195 | // 2. Lookup from context 196 | if (!_type) { 197 | _type = namespace.lookup(typeName, null, this._root); 198 | } 199 | 200 | // 3. Find from imported namespaces 201 | var i, len; 202 | if (!_type) { 203 | for (i = 0, len = this._usingList.length; i < len; i++) { 204 | var _import = this._usingList[i]; 205 | // Find in import exact matches (e.g. import java.lang.String) 206 | _type = this._root.lookdown(_import.name); 207 | } 208 | } 209 | 210 | // 4. Lookdown from Root 211 | if (!_type) { 212 | if (pathName.length > 1) { 213 | _type = this._root.lookdown(pathName); 214 | } else { 215 | _type = this._root.findByName(typeName); 216 | } 217 | } 218 | 219 | return _type; 220 | } 221 | 222 | /** 223 | * Return the class of a given pathNames. If not exists, create the class. 224 | * @param {type.Model} namespace 225 | * @param {Array.} pathNames 226 | * @return {type.Model} Class element corresponding to the pathNames 227 | */ 228 | _ensureClass(namespace, pathNames) { 229 | if (pathNames.length > 0) { 230 | var _className = pathNames.pop(); 231 | var _package = this._ensurePackage(namespace, pathNames); 232 | var _class = _package.findByName(_className); 233 | 234 | if (!_class) { 235 | _class = new type.UMLClass(); 236 | _class._parent = _package; 237 | _class.name = _className; 238 | _class.visibility = type.UMLModelElement.VK_PUBLIC; 239 | _package.ownedElements.push(_class); 240 | } 241 | 242 | return _class; 243 | } 244 | return null; 245 | } 246 | 247 | /** 248 | * Test a given type is a generic collection or not 249 | * @param {Object} typeNode 250 | * @return {string} Collection item type name 251 | */ 252 | _isGenericCollection(typeNode, compilationUnitNode) { 253 | return null; 254 | } 255 | 256 | /** 257 | * Perform Second Phase 258 | * - Create Generalizations 259 | * - Create InterfaceRealizations 260 | * - Create Fields or Associations 261 | * - Resolve Type References 262 | * 263 | * @param {Object} options 264 | */ 265 | performSecondPhase(options) { 266 | var i, len, j, len2, _typeName, _type, _itemTypeName, _itemType, _pathName; 267 | 268 | // Create Generalizations 269 | // if super type not found, create a Class correspond to the super type. 270 | for (i = 0, len = this._extendPendings.length; i < len; i++) { 271 | var _extend = this._extendPendings[i]; 272 | _typeName = _extend.node; 273 | _type = this._findType( 274 | _extend.classifier, 275 | _typeName, 276 | _extend.compilationUnitNode, 277 | ); 278 | 279 | if (!_type) { 280 | // _pathName = this._toPathName(_typeName); 281 | _pathName = [_typeName]; 282 | // if (_extend.kind === "interface") { 283 | // _type = this._ensureInterface(this._root, _pathName); 284 | // } else { 285 | _type = this._ensureClass(this._root, _pathName); 286 | // } 287 | } 288 | 289 | var generalization = new type.UMLGeneralization(); 290 | generalization._parent = _extend.classifier; 291 | generalization.source = _extend.classifier; 292 | generalization.target = _type; 293 | _extend.classifier.ownedElements.push(generalization); 294 | } 295 | 296 | // Create Associations 297 | for (i = 0, len = this._associationPendings.length; i < len; i++) { 298 | var _asso = this._associationPendings[i]; 299 | _typeName = _asso.node; 300 | _type = this._findType( 301 | _asso.classifier, 302 | _typeName, 303 | _asso.node.compilationUnitNode, 304 | ); 305 | _itemTypeName = this._isGenericCollection( 306 | _asso.node.type, 307 | _asso.node.compilationUnitNode, 308 | ); 309 | if (_itemTypeName) { 310 | _itemType = this._findType( 311 | _asso.classifier, 312 | _itemTypeName, 313 | _asso.node.compilationUnitNode, 314 | ); 315 | } else { 316 | _itemType = null; 317 | } 318 | 319 | // if type found, add as Association 320 | if (_type || _itemType) { 321 | for (j = 0, len2 = _asso.node.name.length; j < len2; j++) { 322 | var variableNode = _asso.node.name[j]; 323 | 324 | // Create Association 325 | var association = new type.UMLAssociation(); 326 | association._parent = _asso.classifier; 327 | _asso.classifier.ownedElements.push(association); 328 | 329 | // Set End1 330 | association.end1.reference = _asso.classifier; 331 | association.end1.name = ""; 332 | association.end1.visibility = type.UMLModelElement.VK_PACKAGE; 333 | association.end1.navigable = false; 334 | 335 | // Set End2 336 | if (_itemType) { 337 | association.end2.reference = _itemType; 338 | association.end2.multiplicity = "*"; 339 | this._addTag( 340 | association.end2, 341 | type.Tag.TK_STRING, 342 | "collection", 343 | _asso.node.type.qualifiedName.name, 344 | ); 345 | } else { 346 | association.end2.reference = _type; 347 | } 348 | association.end2.name = variableNode.name; 349 | association.end2.visibility = this._getVisibility( 350 | _asso.node.modifiers, 351 | ); 352 | association.end2.navigable = true; 353 | 354 | // Final Modifier 355 | if (_asso.node.modifiers && _asso.node.modifiers.includes("final")) { 356 | association.end2.isReadOnly = true; 357 | } 358 | 359 | // Static Modifier 360 | if (_asso.node.modifiers && _asso.node.modifiers.includes("static")) { 361 | this._addTag(association.end2, type.Tag.TK_BOOLEAN, "static", true); 362 | } 363 | 364 | // Volatile Modifier 365 | if ( 366 | _asso.node.modifiers && 367 | _asso.node.modifiers.includes("volatile") 368 | ) { 369 | this._addTag( 370 | association.end2, 371 | type.Tag.TK_BOOLEAN, 372 | "volatile", 373 | true, 374 | ); 375 | } 376 | 377 | // Transient Modifier 378 | if ( 379 | _asso.node.modifiers && 380 | _asso.node.modifiers.includes("transient") 381 | ) { 382 | this._addTag( 383 | association.end2, 384 | type.Tag.TK_BOOLEAN, 385 | "transient", 386 | true, 387 | ); 388 | } 389 | } 390 | // if type not found, add as Attribute 391 | } else { 392 | this.translateFieldAsAttribute(options, _asso.classifier, _asso.node); 393 | } 394 | } 395 | 396 | // Resolve Type References 397 | for (i = 0, len = this._typedFeaturePendings.length; i < len; i++) { 398 | var _typedFeature = this._typedFeaturePendings[i]; 399 | _typeName = _typedFeature.node.type; 400 | 401 | // Find type and assign 402 | _type = this._findType( 403 | _typedFeature.namespace, 404 | _typedFeature.node, 405 | _typedFeature.node.compilationUnitNode, 406 | ); 407 | 408 | // if type is exists 409 | if (_type) { 410 | _typedFeature.feature.type = _type; 411 | // if type is not exists 412 | } else { 413 | // if type is generic collection type (e.g. java.util.List) 414 | _itemTypeName = this._isGenericCollection( 415 | _typedFeature.node.type, 416 | _typedFeature.node.compilationUnitNode, 417 | ); 418 | if (_itemTypeName) { 419 | _typeName = _itemTypeName; 420 | _typedFeature.feature.multiplicity = "*"; 421 | this._addTag( 422 | _typedFeature.feature, 423 | type.Tag.TK_STRING, 424 | "collection", 425 | _typedFeature.node.type, 426 | ); 427 | } 428 | 429 | // if type is primitive type 430 | if (cppPrimitiveTypes.includes(_typeName)) { 431 | _typedFeature.feature.type = _typeName; 432 | // otherwise 433 | } else { 434 | _pathName = [_typeName]; 435 | var _newClass = this._ensureClass(this._root, _pathName); 436 | _typedFeature.feature.type = _newClass; 437 | } 438 | } 439 | 440 | // Translate type's arrayDimension to multiplicity 441 | if (_typedFeature.node.type && _typedFeature.node.type.length > 0) { 442 | var _dim = []; 443 | for (j = 0, len2 = _typedFeature.node.type.length; j < len2; j++) { 444 | if (_typedFeature.node.type[j] === "[") { 445 | _dim.push("*"); 446 | } 447 | } 448 | _typedFeature.feature.multiplicity = _dim.join(","); 449 | } 450 | } 451 | } 452 | 453 | /** 454 | * Translate C++ CompilationUnit Node. 455 | * @param {Object} options 456 | * @param {type.Model} namespace 457 | * @param {Object} compilationUnitNode 458 | */ 459 | translateCompilationUnit(options, namespace, compilationUnitNode) { 460 | var _namespace = namespace; 461 | this.translateTypes(options, _namespace, compilationUnitNode["member"]); 462 | } 463 | 464 | /** 465 | * Translate Type Nodes 466 | * @param {Object} options 467 | * @param {type.Model} namespace 468 | * @param {Array.} typeNodeArray 469 | */ 470 | translateTypes(options, namespace, typeNodeArray) { 471 | var _namespace = namespace; 472 | var i, len; 473 | if (typeNodeArray.length > 0) { 474 | for (i = 0, len = typeNodeArray.length; i < len; i++) { 475 | var typeNode = typeNodeArray[i]; 476 | switch (typeNode.node) { 477 | case "namespace": 478 | var _package = this.translatePackage(options, _namespace, typeNode); 479 | if (_package !== null) { 480 | _namespace = _package; 481 | } 482 | // Translate Types 483 | this.translateTypes(options, _namespace, typeNode.body); 484 | break; 485 | case "class": 486 | case "struct": 487 | this.translateClass(options, namespace, typeNode); 488 | break; 489 | case "enum": 490 | this.translateEnum(options, namespace, typeNode); 491 | break; 492 | case "using": 493 | this._usingList.push(typeNode); 494 | break; 495 | } 496 | } 497 | } 498 | } 499 | 500 | /** 501 | * Translate C++ Enum Node. 502 | * @param {Object} options 503 | * @param {type.Model} namespace 504 | * @param {Object} enumNode 505 | */ 506 | translateEnum(options, namespace, enumNode) { 507 | var _enum; 508 | 509 | // Create Enumeration 510 | _enum = new type.UMLEnumeration(); 511 | _enum._parent = namespace; 512 | _enum.name = enumNode.name; 513 | _enum.visibility = this._getVisibility(enumNode.modifiers); 514 | 515 | // CppDoc 516 | // if (enumNode.comment) { 517 | // _enum.documentation = enumNode.comment; 518 | // } 519 | namespace.ownedElements.push(_enum); 520 | 521 | // Translate Type Parameters 522 | // this.translateTypeParameters(options, _enum, enumNode.typeParameters); 523 | if (enumNode.body !== "{") { 524 | // Translate Members 525 | this.translateMembers(options, _enum, enumNode.body); 526 | } 527 | } 528 | 529 | /** 530 | * Translate C++ Class Node. 531 | * @param {Object} options 532 | * @param {type.Model} namespace 533 | * @param {Object} compilationUnitNode 534 | */ 535 | translateClass(options, namespace, classNode) { 536 | var i, len, _class; 537 | 538 | // Create Class 539 | _class = new type.UMLClass(); 540 | _class._parent = namespace; 541 | _class.name = classNode.name; 542 | 543 | // Access Modifiers 544 | _class.visibility = this._getVisibility(classNode.modifiers); 545 | 546 | // Abstract Class 547 | if (classNode.modifiers && classNode.modifiers.includes("abstract")) { 548 | _class.isAbstract = true; 549 | } 550 | 551 | // Final Class 552 | 553 | // CppDoc 554 | // if (classNode.comment) { 555 | // _class.documentation = classNode.comment; 556 | // } 557 | 558 | namespace.ownedElements.push(_class); 559 | 560 | // Register Extends for 2nd Phase Translation 561 | if (classNode["base"]) { 562 | for (i = 0, len = classNode["base"].length; i < len; i++) { 563 | var _extendPending = { 564 | classifier: _class, 565 | node: classNode["base"][i], 566 | kind: "class", 567 | compilationUnitNode: this._currentCompilationUnit, 568 | }; 569 | this._extendPendings.push(_extendPending); 570 | } 571 | } 572 | 573 | // Translate Type Parameters 574 | // this.translateTypeParameters(options, _class, classNode.typeParameters); 575 | 576 | if (classNode.body && classNode.body !== "{") { 577 | // Translate Types 578 | this.translateTypes(options, _class, classNode.body); 579 | // Translate Members 580 | this.translateMembers(options, _class, classNode.body); 581 | } 582 | } 583 | 584 | /** 585 | * Translate Members Nodes 586 | * @param {Object} options 587 | * @param {type.Model} namespace 588 | * @param {Array.} memberNodeArray 589 | */ 590 | translateMembers(options, namespace, memberNodeArray) { 591 | var i, len; 592 | if (memberNodeArray.length > 0) { 593 | for (i = 0, len = memberNodeArray.length; i < len; i++) { 594 | var memberNode = memberNodeArray[i]; 595 | var visibility = this._getVisibility(memberNode.modifiers); 596 | 597 | // Generate public members only if publicOnly == true 598 | if ( 599 | options.publicOnly && 600 | visibility !== type.UMLModelElement.VK_PUBLIC 601 | ) { 602 | continue; 603 | } 604 | 605 | memberNode.compilationUnitNode = this._currentCompilationUnit; 606 | 607 | switch (memberNode.node) { 608 | case "field": 609 | case "property": 610 | if (options.association) { 611 | this.translateFieldAsAssociation(options, namespace, memberNode); 612 | } else { 613 | this.translateFieldAsAttribute(options, namespace, memberNode); 614 | } 615 | break; 616 | case "constructor": 617 | this.translateMethod(options, namespace, memberNode, true); 618 | break; 619 | case "method": 620 | this.translateMethod(options, namespace, memberNode); 621 | break; 622 | case "constant": 623 | // this.translateEnumConstant(options, namespace, memberNode); 624 | break; 625 | } 626 | } 627 | } 628 | } 629 | 630 | /** 631 | * Translate Method 632 | * @param {Object} options 633 | * @param {type.Model} namespace 634 | * @param {Object} methodNode 635 | * @param {boolean} isConstructor 636 | */ 637 | translateMethod(options, namespace, methodNode, isConstructor) { 638 | var i, len; 639 | var _operation = new type.UMLOperation(); 640 | _operation._parent = namespace; 641 | _operation.name = methodNode.name; 642 | 643 | if (!isConstructor) { 644 | _operation.name = methodNode.name; 645 | } 646 | 647 | namespace.operations.push(_operation); 648 | 649 | // Modifiers 650 | _operation.visibility = this._getVisibility(methodNode.modifiers); 651 | if (methodNode.modifiers && methodNode.modifiers.includes("static")) { 652 | _operation.isStatic = true; 653 | } 654 | if (methodNode.modifiers && methodNode.modifiers.includes("abstract")) { 655 | _operation.isAbstract = true; 656 | } 657 | 658 | // Constructor 659 | if (isConstructor) { 660 | _operation.stereotype = "constructor"; 661 | } 662 | 663 | // Formal Parameters 664 | if (methodNode.parameter && methodNode.parameter.length > 0) { 665 | for (i = 0, len = methodNode.parameter.length; i < len; i++) { 666 | var parameterNode = methodNode.parameter[i]; 667 | parameterNode.compilationUnitNode = methodNode.compilationUnitNode; 668 | this.translateParameter(options, _operation, parameterNode); 669 | } 670 | } 671 | 672 | // Return Type 673 | if (methodNode.type) { 674 | var _returnParam = new type.UMLParameter(); 675 | _returnParam._parent = _operation; 676 | _returnParam.name = ""; 677 | _returnParam.direction = type.UMLParameter.DK_RETURN; 678 | // Add to _typedFeaturePendings 679 | this._typedFeaturePendings.push({ 680 | namespace: namespace, 681 | feature: _returnParam, 682 | node: methodNode, 683 | }); 684 | _operation.parameters.push(_returnParam); 685 | } 686 | 687 | // Throws 688 | // if (methodNode.throws) { 689 | // for (i = 0, len = methodNode.throws.length; i < len; i++) { 690 | // var _throwNode = methodNode.throws[i]; 691 | // var _throwPending = { 692 | // operation: _operation, 693 | // node: _throwNode, 694 | // compilationUnitNode: methodNode.compilationUnitNode 695 | // }; 696 | // this._throwPendings.push(_throwPending); 697 | // } 698 | // } 699 | 700 | // CppDoc 701 | // if (methodNode.comment) { 702 | // _operation.documentation = methodNode.comment; 703 | // } 704 | 705 | // "default" for Annotation Type Element 706 | // if (methodNode.defaultValue) { 707 | // this._addTag(_operation, type.Tag.TK_STRING, "default", methodNode.defaultValue); 708 | // } 709 | 710 | // Translate Type Parameters 711 | // this.translateTypeParameters(options, _operation, methodNode.typeParameters); 712 | } 713 | 714 | /** 715 | * Translate Method Parameters 716 | * @param {Object} options 717 | * @param {type.Model} namespace 718 | * @param {Object} parameterNode 719 | */ 720 | translateParameter(options, namespace, parameterNode) { 721 | var _parameter = new type.UMLParameter(); 722 | _parameter._parent = namespace; 723 | _parameter.name = parameterNode.name; 724 | namespace.parameters.push(_parameter); 725 | 726 | // Add to _typedFeaturePendings 727 | this._typedFeaturePendings.push({ 728 | namespace: namespace._parent, 729 | feature: _parameter, 730 | node: parameterNode, 731 | }); 732 | } 733 | 734 | /** 735 | * Translate C++ Field Node as UMLAttribute. 736 | * @param {Object} options 737 | * @param {type.Model} namespace 738 | * @param {Object} fieldNode 739 | */ 740 | translateFieldAsAttribute(options, namespace, fieldNode) { 741 | var i, len; 742 | if (fieldNode.name && fieldNode.name.length > 0) { 743 | for (i = 0, len = fieldNode.name.length; i < len; i++) { 744 | var variableNode = fieldNode.name[i]; 745 | 746 | // Create Attribute 747 | var _attribute = new type.UMLAttribute(); 748 | _attribute._parent = namespace; 749 | _attribute.name = variableNode.name; 750 | 751 | // Access Modifiers 752 | _attribute.visibility = this._getVisibility(fieldNode.modifiers); 753 | if (variableNode.initialize) { 754 | _attribute.defaultValue = variableNode.initialize; 755 | } 756 | 757 | // Static Modifier 758 | if (fieldNode.modifiers && fieldNode.modifiers.includes("static")) { 759 | _attribute.isStatic = true; 760 | } 761 | 762 | // Final Modifier 763 | 764 | // Volatile Modifier 765 | if (fieldNode.modifiers && fieldNode.modifiers.includes("volatile")) { 766 | this._addTag(_attribute, type.Tag.TK_BOOLEAN, "volatile", true); 767 | } 768 | 769 | // CppDoc 770 | // if (fieldNode.comment) { 771 | // _attribute.documentation = fieldNode.comment; 772 | // } 773 | 774 | namespace.attributes.push(_attribute); 775 | 776 | // Add to _typedFeaturePendings 777 | var _typedFeature = { 778 | namespace: namespace, 779 | feature: _attribute, 780 | node: fieldNode, 781 | }; 782 | this._typedFeaturePendings.push(_typedFeature); 783 | } 784 | } 785 | } 786 | 787 | /** 788 | * Add a Tag 789 | * @param {type.Model} elem 790 | * @param {string} kind Kind of Tag 791 | * @param {string} name 792 | * @param {?} value Value of Tag 793 | */ 794 | _addTag(elem, kind, name, value) { 795 | var tag = new type.Tag(); 796 | tag._parent = elem; 797 | tag.name = name; 798 | tag.kind = kind; 799 | switch (kind) { 800 | case type.Tag.TK_STRING: 801 | tag.value = value; 802 | break; 803 | case type.Tag.TK_BOOLEAN: 804 | tag.checked = value; 805 | break; 806 | case type.Tag.TK_NUMBER: 807 | tag.number = value; 808 | break; 809 | case type.Tag.TK_REFERENCE: 810 | tag.reference = value; 811 | break; 812 | case type.Tag.TK_HIDDEN: 813 | tag.value = value; 814 | break; 815 | } 816 | elem.tags.push(tag); 817 | } 818 | 819 | /** 820 | * Translate C++ Field Node as UMLAssociation. 821 | * @param {Object} options 822 | * @param {type.Model} namespace 823 | * @param {Object} fieldNode 824 | */ 825 | translateFieldAsAssociation(options, namespace, fieldNode) { 826 | if (fieldNode.name && fieldNode.name.length > 0) { 827 | // Add to _associationPendings 828 | var _associationPending = { 829 | classifier: namespace, 830 | node: fieldNode, 831 | }; 832 | this._associationPendings.push(_associationPending); 833 | } 834 | } 835 | 836 | /** 837 | * Return visiblity from modifiers 838 | * 839 | * @param {Array.} modifiers 840 | * @return {string} Visibility constants for UML Elements 841 | */ 842 | _getVisibility(modifiers) { 843 | modifiers = modifiers || []; 844 | if (modifiers.includes("public")) { 845 | return type.UMLModelElement.VK_PUBLIC; 846 | } else if (modifiers.includes("protected")) { 847 | return type.UMLModelElement.VK_PROTECTED; 848 | } else if (modifiers.includes("private")) { 849 | return type.UMLModelElement.VK_PRIVATE; 850 | } 851 | return type.UMLModelElement.VK_PACKAGE; 852 | } 853 | 854 | /** 855 | * Translate C++ Package Node. 856 | * @param {Object} options 857 | * @param {type.Model} namespace 858 | * @param {Object} compilationUnitNode 859 | */ 860 | translatePackage(options, namespace, packageNode) { 861 | if (packageNode && packageNode.name) { 862 | var packageName = packageNode.name; 863 | return this._ensurePackage(namespace, packageName); 864 | } 865 | return null; 866 | } 867 | 868 | /** 869 | * Return the package of a given packageName. If not exists, create the package. 870 | * @param {type.Model} namespace 871 | * @param {Array.} packageName 872 | * @return {type.Model} Package element corresponding to the packageName 873 | */ 874 | _ensurePackage(namespace, packageName) { 875 | if (packageName.length > 0) { 876 | var name = packageName; 877 | if (name && name.length > 0) { 878 | var elem = namespace.findByName(name); 879 | if (elem !== null) { 880 | // Package exists 881 | return elem; 882 | } else { 883 | // Package not exists, then create one. 884 | var _package = new type.UMLPackage(); 885 | namespace.ownedElements.push(_package); 886 | _package._parent = namespace; 887 | _package.name = name; 888 | return _package; 889 | } 890 | } 891 | } else { 892 | return namespace; 893 | } 894 | } 895 | 896 | /** 897 | * Perform First Phase 898 | * - Create Packages, Classes, Interfaces, Enums, AnnotationTypes. 899 | * 900 | * @param {Object} options 901 | * @return {$.Promise} 902 | */ 903 | performFirstPhase(options) { 904 | this._files.forEach((file) => { 905 | var data = fs.readFileSync(file, "utf8"); 906 | try { 907 | var ast = parser.parse(data); 908 | var results = []; 909 | for (var property in ast) { 910 | var value = ast[property]; 911 | if (value) { 912 | results.push(property.toString() + ": " + value); 913 | } 914 | } 915 | this._currentCompilationUnit = ast; 916 | this._currentCompilationUnit.file = file; 917 | this.translateCompilationUnit(options, this._root, ast); 918 | } catch (ex) { 919 | console.error("[C++] Failed to parse - " + file); 920 | console.error(ex); 921 | } 922 | }); 923 | } 924 | } 925 | 926 | /** 927 | * Analyze all C++ files in basePath 928 | * @param {string} basePath 929 | * @param {Object} options 930 | */ 931 | function analyze(basePath, options) { 932 | var cppAnalyzer = new CppCodeAnalyzer(); 933 | 934 | function visit(base) { 935 | var stat = fs.lstatSync(base); 936 | if (stat.isFile()) { 937 | var ext = path.extname(base).toLowerCase(); 938 | if (ext === ".cpp" || ext === ".h") { 939 | cppAnalyzer.addFile(base); 940 | } 941 | } else if (stat.isDirectory()) { 942 | var files = fs.readdirSync(base); 943 | if (files && files.length > 0) { 944 | files.forEach((entry) => { 945 | var fullPath = path.join(base, entry); 946 | visit(fullPath); 947 | }); 948 | } 949 | } 950 | } 951 | 952 | // Traverse all file entries 953 | visit(basePath); 954 | 955 | // Perform reverse engineering 956 | cppAnalyzer.analyze(options); 957 | } 958 | 959 | exports.analyze = analyze; 960 | -------------------------------------------------------------------------------- /code-generator.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2018 MKLab. All rights reserved. 3 | * Copyright (c) 2014 Sebastian Schleemilch. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | * DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | const _CPP_CODE_GEN_H = "h"; 26 | const _CPP_CODE_GEN_CPP = "cpp"; 27 | 28 | const path = require("path"); 29 | const fs = require("fs"); 30 | const codegen = require("./codegen-utils"); 31 | 32 | var copyrightHeader = 33 | "/* Test header @ toori67 \n * This is Test\n * also test\n * also test again\n */"; 34 | var versionString = "v0.0.1"; 35 | 36 | /** 37 | * Cpp Code Generator 38 | */ 39 | class CppCodeGenerator { 40 | /** 41 | * @constructor 42 | * 43 | * @param {type.UMLPackage} baseModel 44 | * @param {string} basePath generated files and directories to be placed 45 | * 46 | */ 47 | constructor(baseModel, basePath) { 48 | /** @member {type.Model} */ 49 | this.baseModel = baseModel; 50 | 51 | /** @member {string} */ 52 | this.basePath = basePath; 53 | 54 | var doc = ""; 55 | if ( 56 | app.project.getProject().name && 57 | app.project.getProject().name.length > 0 58 | ) { 59 | doc += "\nProject " + app.project.getProject().name; 60 | } 61 | if ( 62 | app.project.getProject().author && 63 | app.project.getProject().author.length > 0 64 | ) { 65 | doc += "\n@author " + app.project.getProject().author; 66 | } 67 | if ( 68 | app.project.getProject().version && 69 | app.project.getProject().version.length > 0 70 | ) { 71 | doc += "\n@version " + app.project.getProject().version; 72 | } 73 | copyrightHeader = this.getDocuments(doc); 74 | } 75 | 76 | /** 77 | * Return Indent String based on options 78 | * @param {Object} options 79 | * @return {string} 80 | */ 81 | getIndentString(options) { 82 | if (options.useTab) { 83 | return "\t"; 84 | } else { 85 | var i, len; 86 | var indent = []; 87 | for (i = 0, len = options.indentSpaces; i < len; i++) { 88 | indent.push(" "); 89 | } 90 | return indent.join(""); 91 | } 92 | } 93 | 94 | generate(elem, basePath, options) { 95 | this.genOptions = options; 96 | 97 | var getFilePath = (extenstions) => { 98 | var absPath = basePath + "/" + elem.name + "."; 99 | if (extenstions === _CPP_CODE_GEN_H) { 100 | absPath += _CPP_CODE_GEN_H; 101 | } else { 102 | absPath += _CPP_CODE_GEN_CPP; 103 | } 104 | return absPath; 105 | }; 106 | 107 | var writeEnumeration = (codeWriter, elem, cppCodeGen) => { 108 | var i; 109 | var modifierList = cppCodeGen.getModifiers(elem); 110 | var modifierStr = ""; 111 | for (i = 0; i < modifierList.length; i++) { 112 | modifierStr += modifierList[i] + " "; 113 | } 114 | codeWriter.writeLine( 115 | modifierStr + 116 | "enum " + 117 | elem.name + 118 | " { " + 119 | elem.literals.map((lit) => lit.name).join(", ") + 120 | " };", 121 | ); 122 | }; 123 | 124 | var writeClassHeader = (codeWriter, elem, cppCodeGen) => { 125 | var i; 126 | var write = (items) => { 127 | var i; 128 | for (i = 0; i < items.length; i++) { 129 | var item = items[i]; 130 | if ( 131 | item instanceof type.UMLAttribute || 132 | item instanceof type.UMLAssociationEnd 133 | ) { 134 | // if write member variable 135 | codeWriter.writeLine(cppCodeGen.getMemberVariable(item)); 136 | } else if (item instanceof type.UMLOperation) { 137 | // if write method 138 | codeWriter.writeLine(cppCodeGen.getMethod(item, false)); 139 | } else if (item instanceof type.UMLClass) { 140 | writeClassHeader(codeWriter, item, cppCodeGen); 141 | } else if (item instanceof type.UMLEnumeration) { 142 | writeEnumeration(codeWriter, item, cppCodeGen); 143 | } 144 | } 145 | }; 146 | 147 | var writeInheritance = (elem) => { 148 | var inheritString = ": "; 149 | var genList = cppCodeGen.getSuperClasses(elem); 150 | if (genList.length === 0) { 151 | return ""; 152 | } 153 | var i; 154 | var term = []; 155 | for (i = 0; i < genList.length; i++) { 156 | var generalization = genList[i]; 157 | // public AAA, private BBB 158 | term.push( 159 | generalization.visibility + " " + generalization.target.name, 160 | ); 161 | } 162 | inheritString += term.join(", "); 163 | return inheritString; 164 | }; 165 | 166 | // member variable 167 | var memberAttr = elem.attributes.slice(0); 168 | var associations = app.repository.getRelationshipsOf( 169 | elem, 170 | function (rel) { 171 | return rel instanceof type.UMLAssociation; 172 | }, 173 | ); 174 | for (i = 0; i < associations.length; i++) { 175 | var asso = associations[i]; 176 | if ( 177 | asso.end1.reference === elem && 178 | asso.end2.navigable !== "notNavigable" && 179 | asso.end2.name.length !== 0 180 | ) { 181 | memberAttr.push(asso.end2); 182 | } else if ( 183 | asso.end2.reference === elem && 184 | asso.end1.navigable !== "notNavigable" && 185 | asso.end1.name.length !== 0 186 | ) { 187 | memberAttr.push(asso.end1); 188 | } 189 | } 190 | 191 | // method 192 | var methodList = elem.operations.slice(0); 193 | var innerElement = []; 194 | for (i = 0; i < elem.ownedElements.length; i++) { 195 | var element = elem.ownedElements[i]; 196 | if ( 197 | element instanceof type.UMLClass || 198 | element instanceof type.UMLEnumeration 199 | ) { 200 | innerElement.push(element); 201 | } 202 | } 203 | 204 | var allMembers = memberAttr.concat(methodList).concat(innerElement); 205 | var classfiedAttributes = cppCodeGen.classifyVisibility(allMembers); 206 | var finalModifier = ""; 207 | if (elem.isFinalSpecialization === true || elem.isLeaf === true) { 208 | finalModifier = " final "; 209 | } 210 | var templatePart = cppCodeGen.getTemplateParameter(elem); 211 | if (templatePart.length > 0) { 212 | codeWriter.writeLine(templatePart); 213 | } 214 | 215 | codeWriter.writeLine( 216 | "class " + elem.name + finalModifier + writeInheritance(elem) + " {", 217 | ); 218 | if (classfiedAttributes._public.length > 0) { 219 | codeWriter.writeLine("public: "); 220 | codeWriter.indent(); 221 | write(classfiedAttributes._public); 222 | codeWriter.outdent(); 223 | } 224 | if (classfiedAttributes._protected.length > 0) { 225 | codeWriter.writeLine("protected: "); 226 | codeWriter.indent(); 227 | write(classfiedAttributes._protected); 228 | codeWriter.outdent(); 229 | } 230 | if (classfiedAttributes._private.length > 0) { 231 | codeWriter.writeLine("private: "); 232 | codeWriter.indent(); 233 | write(classfiedAttributes._private); 234 | codeWriter.outdent(); 235 | } 236 | 237 | codeWriter.writeLine("};"); 238 | }; 239 | 240 | var writeClassBody = (codeWriter, elem, cppCodeGen) => { 241 | var i = 0; 242 | var item; 243 | var writeClassMethod = (elemList) => { 244 | for (i = 0; i < elemList._public.length; i++) { 245 | item = elemList._public[i]; 246 | if (item instanceof type.UMLOperation) { 247 | // if write method 248 | codeWriter.writeLine(cppCodeGen.getMethod(item, true)); 249 | } else if (item instanceof type.UMLClass) { 250 | writeClassBody(codeWriter, item, cppCodeGen); 251 | } 252 | } 253 | 254 | for (i = 0; i < elemList._protected.length; i++) { 255 | item = elemList._protected[i]; 256 | if (item instanceof type.UMLOperation) { 257 | // if write method 258 | codeWriter.writeLine(cppCodeGen.getMethod(item, true)); 259 | } else if (item instanceof type.UMLClass) { 260 | writeClassBody(codeWriter, item, cppCodeGen); 261 | } 262 | } 263 | 264 | for (i = 0; i < elemList._private.length; i++) { 265 | item = elemList._private[i]; 266 | if (item instanceof type.UMLOperation) { 267 | // if write method 268 | codeWriter.writeLine(cppCodeGen.getMethod(item, true)); 269 | } else if (item instanceof type.UMLClass) { 270 | writeClassBody(codeWriter, item, cppCodeGen); 271 | } 272 | } 273 | }; 274 | 275 | // parsing class 276 | var methodList = cppCodeGen.classifyVisibility(elem.operations.slice(0)); 277 | var docs = elem.name + " implementation\n\n"; 278 | if (typeof elem.documentation === "string") { 279 | docs += elem.documentation; 280 | } 281 | codeWriter.writeLine(cppCodeGen.getDocuments(docs)); 282 | writeClassMethod(methodList); 283 | 284 | // parsing nested class 285 | var innerClass = []; 286 | for (i = 0; i < elem.ownedElements.length; i++) { 287 | var element = elem.ownedElements[i]; 288 | if (element instanceof type.UMLClass) { 289 | innerClass.push(element); 290 | } 291 | } 292 | if (innerClass.length > 0) { 293 | innerClass = cppCodeGen.classifyVisibility(innerClass); 294 | writeClassMethod(innerClass); 295 | } 296 | }; 297 | 298 | var fullPath, file; 299 | 300 | // Package -> as namespace or not 301 | if (elem instanceof type.UMLPackage) { 302 | fullPath = path.join(basePath, elem.name); 303 | fs.mkdirSync(fullPath); 304 | if (Array.isArray(elem.ownedElements)) { 305 | elem.ownedElements.forEach((child) => { 306 | return this.generate(child, fullPath, options); 307 | }); 308 | } 309 | } else if (elem instanceof type.UMLClass) { 310 | // generate class header elem_name.h 311 | file = getFilePath(_CPP_CODE_GEN_H); 312 | fs.writeFileSync( 313 | file, 314 | this.writeHeaderSkeletonCode(elem, options, writeClassHeader), 315 | ); 316 | // generate class cpp elem_name.cpp 317 | if (options.genCpp) { 318 | file = getFilePath(_CPP_CODE_GEN_CPP); 319 | fs.writeFileSync( 320 | file, 321 | this.writeBodySkeletonCode(elem, options, writeClassBody), 322 | ); 323 | } 324 | } else if (elem instanceof type.UMLInterface) { 325 | /* 326 | * interface will convert to class which only contains virtual method and member variable. 327 | */ 328 | // generate interface header ONLY elem_name.h 329 | file = getFilePath(_CPP_CODE_GEN_H); 330 | fs.writeFileSync( 331 | file, 332 | this.writeHeaderSkeletonCode(elem, options, writeClassHeader), 333 | ); 334 | } else if (elem instanceof type.UMLEnumeration) { 335 | // generate enumeration header ONLY elem_name.h 336 | file = getFilePath(_CPP_CODE_GEN_H); 337 | fs.writeFileSync( 338 | file, 339 | this.writeHeaderSkeletonCode(elem, options, writeEnumeration), 340 | ); 341 | } 342 | } 343 | 344 | /** 345 | * Write *.h file. Implement functor to each uml type. 346 | * Returns text 347 | * 348 | * @param {Object} elem 349 | * @param {Object} options 350 | * @param {Object} funct 351 | * @return {string} 352 | */ 353 | writeHeaderSkeletonCode(elem, options, funct) { 354 | var headerString = "_" + elem.name.toUpperCase() + "_H"; 355 | var codeWriter = new codegen.CodeWriter(this.getIndentString(options)); 356 | var includePart = this.getIncludePart(elem); 357 | codeWriter.writeLine(copyrightHeader); 358 | codeWriter.writeLine(); 359 | codeWriter.writeLine("#ifndef " + headerString); 360 | codeWriter.writeLine("#define " + headerString); 361 | codeWriter.writeLine(); 362 | 363 | if (includePart.length > 0) { 364 | codeWriter.writeLine(includePart); 365 | codeWriter.writeLine(); 366 | } 367 | funct(codeWriter, elem, this); 368 | 369 | codeWriter.writeLine(); 370 | codeWriter.writeLine("#endif //" + headerString); 371 | return codeWriter.getData(); 372 | } 373 | 374 | /** 375 | * Write *.cpp file. Implement functor to each uml type. 376 | * Returns text 377 | * 378 | * @param {Object} elem 379 | * @param {Object} options 380 | * @param {Object} functor 381 | * @return {Object} string 382 | */ 383 | writeBodySkeletonCode(elem, options, funct) { 384 | var codeWriter = new codegen.CodeWriter(this.getIndentString(options)); 385 | codeWriter.writeLine(copyrightHeader); 386 | codeWriter.writeLine(); 387 | codeWriter.writeLine('#include "' + elem.name + '.h"'); 388 | codeWriter.writeLine(); 389 | funct(codeWriter, elem, this); 390 | return codeWriter.getData(); 391 | } 392 | 393 | /** 394 | * Parsing template parameter 395 | * 396 | * @param {Object} elem 397 | * @return {Object} string 398 | */ 399 | getTemplateParameter(elem) { 400 | var i; 401 | var returnTemplateString = ""; 402 | if (elem.templateParameters.length <= 0) { 403 | return returnTemplateString; 404 | } 405 | var term = []; 406 | returnTemplateString = "template<"; 407 | for (i = 0; i < elem.templateParameters.length; i++) { 408 | var template = elem.templateParameters[i]; 409 | var templateStr = template.parameterType + " "; 410 | templateStr += template.name + " "; 411 | if (template.defaultValue.length !== 0) { 412 | templateStr += " = " + template.defaultValue; 413 | } 414 | term.push(templateStr); 415 | } 416 | returnTemplateString += term.join(", "); 417 | returnTemplateString += ">"; 418 | return returnTemplateString; 419 | } 420 | 421 | /** 422 | * Parsing include header 423 | * 424 | * @param {Object} elem 425 | * @return {Object} string 426 | */ 427 | getIncludePart(elem) { 428 | var i; 429 | var trackingHeader = (elem, target) => { 430 | var header = ""; 431 | var elementString = ""; 432 | var targetString = ""; 433 | var i; 434 | 435 | while (elem._parent._parent !== null) { 436 | elementString = 437 | elementString.length !== 0 438 | ? elem.name + "/" + elementString 439 | : elem.name; 440 | elem = elem._parent; 441 | } 442 | while (target._parent._parent !== null) { 443 | targetString = 444 | targetString.length !== 0 445 | ? target.name + "/" + targetString 446 | : target.name; 447 | target = target._parent; 448 | } 449 | 450 | var idx; 451 | for ( 452 | i = 0; 453 | i < (elementString.length < targetString.length) 454 | ? elementString.length 455 | : targetString.length; 456 | i++ 457 | ) { 458 | if (elementString[i] === targetString[i]) { 459 | if (elementString[i] === "/" && targetString[i] === "/") { 460 | idx = i + 1; 461 | } 462 | } else { 463 | break; 464 | } 465 | } 466 | 467 | // remove common path 468 | elementString = elementString.substring(idx, elementString.length); 469 | targetString = targetString.substring(idx, targetString.length); 470 | for (i = 0; i < elementString.split("/").length - 1; i++) { 471 | header += "../"; 472 | } 473 | header += targetString; 474 | return header; 475 | }; 476 | 477 | var headerString = ""; 478 | if (app.repository.getRelationshipsOf(elem).length <= 0) { 479 | return ""; 480 | } 481 | var associations = app.repository.getRelationshipsOf(elem, function (rel) { 482 | return rel instanceof type.UMLAssociation; 483 | }); 484 | var realizations = app.repository.getRelationshipsOf(elem, function (rel) { 485 | return ( 486 | rel instanceof type.UMLInterfaceRealization || 487 | rel instanceof type.UMLGeneralization 488 | ); 489 | }); 490 | 491 | // check for interface or class 492 | for (i = 0; i < realizations.length; i++) { 493 | var realize = realizations[i]; 494 | if (realize.target === elem) { 495 | continue; 496 | } 497 | headerString += 498 | '#include "' + trackingHeader(elem, realize.target) + '.h"\n'; 499 | } 500 | 501 | // check for member variable 502 | for (i = 0; i < associations.length; i++) { 503 | var asso = associations[i]; 504 | var target; 505 | if ( 506 | asso.end1.reference === elem && 507 | asso.end2.navigable !== "notNavigable" && 508 | asso.end2.name.length !== 0 509 | ) { 510 | target = asso.end2.reference; 511 | } else if ( 512 | asso.end2.reference === elem && 513 | asso.end1.navigable !== "notNavigable" && 514 | asso.end1.name.length !== 0 515 | ) { 516 | target = asso.end1.reference; 517 | } else { 518 | continue; 519 | } 520 | if (target === elem) { 521 | continue; 522 | } 523 | headerString += '#include "' + trackingHeader(elem, target) + '.h"\n'; 524 | } 525 | return headerString; 526 | } 527 | 528 | /** 529 | * Classfy method and attribute by accessor.(public, private, protected) 530 | * 531 | * @param {Object} items 532 | * @return {Object} list 533 | */ 534 | classifyVisibility(items) { 535 | var publicList = []; 536 | var protectedList = []; 537 | var privateList = []; 538 | var i; 539 | for (i = 0; i < items.length; i++) { 540 | var item = items[i]; 541 | var visib = this.getVisibility(item); 542 | 543 | if (visib === "public") { 544 | publicList.push(item); 545 | } else if (visib === "private") { 546 | privateList.push(item); 547 | } else { 548 | // if modifier not setted, consider it as protected 549 | protectedList.push(item); 550 | } 551 | } 552 | return { 553 | _public: publicList, 554 | _protected: protectedList, 555 | _private: privateList, 556 | }; 557 | } 558 | 559 | /** 560 | * generate variables from attributes[i] 561 | * 562 | * @param {Object} elem 563 | * @return {Object} string 564 | */ 565 | getMemberVariable(elem) { 566 | if (elem.name.length > 0) { 567 | var terms = []; 568 | // doc 569 | var docs = this.getDocuments(elem.documentation); 570 | // modifiers 571 | var _modifiers = this.getModifiers(elem); 572 | if (_modifiers.length > 0) { 573 | terms.push(_modifiers.join(" ")); 574 | } 575 | // type 576 | terms.push(this.getType(elem)); 577 | // name 578 | terms.push(elem.name); 579 | // initial value 580 | if (elem.defaultValue && elem.defaultValue.length > 0) { 581 | terms.push("= " + elem.defaultValue); 582 | } 583 | return docs + terms.join(" ") + ";"; 584 | } 585 | } 586 | 587 | /** 588 | * generate methods from operations[i] 589 | * 590 | * @param {Object} elem 591 | * @param {boolean} isCppBody 592 | * @return {Object} string 593 | */ 594 | getMethod(elem, isCppBody) { 595 | if (elem.name.length > 0) { 596 | var docs = elem.documentation; 597 | var i; 598 | var methodStr = ""; 599 | // var isVirtaul = false 600 | // TODO virtual fianl static 키워드는 섞어 쓸수가 없다 601 | if (elem.isStatic === true) { 602 | methodStr += "static "; 603 | } else if (elem.isAbstract === true) { 604 | methodStr += "virtual "; 605 | } 606 | 607 | var returnTypeParam = elem.parameters.filter(function (params) { 608 | return params.direction === "return"; 609 | }); 610 | var inputParams = elem.parameters.filter(function (params) { 611 | return params.direction === "in"; 612 | }); 613 | var inputParamStrings = []; 614 | for (i = 0; i < inputParams.length; i++) { 615 | var inputParam = inputParams[i]; 616 | inputParamStrings.push( 617 | this.getType(inputParam) + " " + inputParam.name, 618 | ); 619 | docs += "\n@param " + inputParam.name; 620 | } 621 | 622 | methodStr += 623 | (returnTypeParam.length > 0 624 | ? this.getType(returnTypeParam[0]) 625 | : "void") + " "; 626 | 627 | if (isCppBody) { 628 | var telem = elem; 629 | var specifier = ""; 630 | 631 | while (telem._parent instanceof type.UMLClass) { 632 | specifier = telem._parent.name + "::" + specifier; 633 | telem = telem._parent; 634 | } 635 | 636 | var indentLine = ""; 637 | 638 | for (i = 0; i < this.genOptions.indentSpaces; i++) { 639 | indentLine += " "; 640 | } 641 | 642 | methodStr += specifier; 643 | methodStr += elem.name; 644 | methodStr += "(" + inputParamStrings.join(", ") + ")" + " {\n"; 645 | if (returnTypeParam.length > 0) { 646 | var returnType = this.getType(returnTypeParam[0]); 647 | if (returnType === "boolean" || returnType === "bool") { 648 | methodStr += indentLine + "return false;"; 649 | } else if ( 650 | returnType === "int" || 651 | returnType === "long" || 652 | returnType === "short" || 653 | returnType === "byte" 654 | ) { 655 | methodStr += indentLine + "return 0;"; 656 | } else if (returnType === "double" || returnType === "float") { 657 | methodStr += indentLine + "return 0.0;"; 658 | } else if (returnType === "char") { 659 | methodStr += indentLine + "return '0';"; 660 | } else if (returnType === "string" || returnType === "String") { 661 | methodStr += indentLine + 'return "";'; 662 | } else if (returnType === "void") { 663 | methodStr += indentLine + "return;"; 664 | } else { 665 | methodStr += indentLine + "return null;"; 666 | } 667 | docs += "\n@return " + returnType; 668 | } 669 | methodStr += "\n}"; 670 | } else { 671 | methodStr += elem.name; 672 | methodStr += "(" + inputParamStrings.join(", ") + ")"; 673 | if (elem.isLeaf === true) { 674 | methodStr += " final"; 675 | } else if (elem.isAbstract === true) { 676 | // TODO 만약 virtual 이면 모두 pure virtual? 체크 할것 677 | methodStr += " = 0"; 678 | } 679 | methodStr += ";"; 680 | } 681 | return "\n" + this.getDocuments(docs) + methodStr; 682 | } 683 | } 684 | 685 | /** 686 | * generate doc string from doc element 687 | * 688 | * @param {Object} text 689 | * @return {Object} string 690 | */ 691 | getDocuments(text) { 692 | var docs = ""; 693 | if (typeof text === "string" && text.length !== 0) { 694 | var lines = text.trim().split("\n"); 695 | docs += "/**\n"; 696 | var i; 697 | for (i = 0; i < lines.length; i++) { 698 | docs += " * " + lines[i] + "\n"; 699 | } 700 | docs += " */\n"; 701 | } 702 | return docs; 703 | } 704 | 705 | /** 706 | * parsing visibility from element 707 | * 708 | * @param {Object} elem 709 | * @return {Object} string 710 | */ 711 | getVisibility(elem) { 712 | switch (elem.visibility) { 713 | case type.UMLModelElement.VK_PUBLIC: 714 | return "public"; 715 | case type.UMLModelElement.VK_PROTECTED: 716 | return "protected"; 717 | case type.UMLModelElement.VK_PRIVATE: 718 | return "private"; 719 | } 720 | return null; 721 | } 722 | 723 | /** 724 | * parsing modifiers from element 725 | * 726 | * @param {Object} elem 727 | * @return {Object} list 728 | */ 729 | getModifiers(elem) { 730 | var modifiers = []; 731 | if (elem.isStatic === true) { 732 | modifiers.push("static"); 733 | } 734 | if (elem.isReadOnly === true) { 735 | modifiers.push("const"); 736 | } 737 | if (elem.isAbstract === true) { 738 | modifiers.push("virtual"); 739 | } 740 | return modifiers; 741 | } 742 | 743 | /** 744 | * parsing type from element 745 | * 746 | * @param {Object} elem 747 | * @return {Object} string 748 | */ 749 | getType(elem) { 750 | var _type = "void"; 751 | if (elem instanceof type.UMLAssociationEnd) { 752 | // member variable from association 753 | if ( 754 | elem.reference instanceof type.UMLModelElement && 755 | elem.reference.name.length > 0 756 | ) { 757 | _type = elem.reference.name; 758 | } 759 | } else { 760 | // member variable inside class 761 | if ( 762 | elem.type instanceof type.UMLModelElement && 763 | elem.type.name.length > 0 764 | ) { 765 | _type = elem.type.name; 766 | } else if (typeof elem.type === "string" && elem.type.length > 0) { 767 | _type = elem.type; 768 | } 769 | } 770 | 771 | // multiplicity 772 | if (elem.multiplicity) { 773 | if (["0..*", "1..*", "*"].includes(elem.multiplicity.trim())) { 774 | if (elem.isOrdered === true) { 775 | _type = "vector<" + _type + ">"; 776 | } else { 777 | _type = "vector<" + _type + ">"; 778 | } 779 | } else if ( 780 | elem.multiplicity !== "1" && 781 | elem.multiplicity.match(/^\d+$/) 782 | ) { 783 | // number 784 | // TODO check here 785 | _type += "[]"; 786 | } 787 | } 788 | return _type; 789 | } 790 | 791 | /** 792 | * get all super class / interface from element 793 | * 794 | * @param {Object} elem 795 | * @return {Object} list 796 | */ 797 | getSuperClasses(elem) { 798 | var generalizations = app.repository.getRelationshipsOf( 799 | elem, 800 | function (rel) { 801 | return ( 802 | (rel instanceof type.UMLGeneralization || 803 | rel instanceof type.UMLInterfaceRealization) && 804 | rel.source === elem 805 | ); 806 | }, 807 | ); 808 | return generalizations; 809 | } 810 | } 811 | 812 | function generate(baseModel, basePath, options) { 813 | var cppCodeGenerator = new CppCodeGenerator(baseModel, basePath); 814 | cppCodeGenerator.generate(baseModel, basePath, options); 815 | } 816 | 817 | function getVersion() { 818 | return versionString; 819 | } 820 | 821 | exports.generate = generate; 822 | exports.getVersion = getVersion; 823 | -------------------------------------------------------------------------------- /codegen-utils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2018 MKLab. All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | * 22 | */ 23 | 24 | /** 25 | * CodeWriter 26 | */ 27 | class CodeWriter { 28 | /** 29 | * @constructor 30 | */ 31 | constructor(indentString) { 32 | /** @member {Array.} lines */ 33 | this.lines = []; 34 | 35 | /** @member {string} indentString */ 36 | this.indentString = indentString || " "; // default 4 spaces 37 | 38 | /** @member {Array.} indentations */ 39 | this.indentations = []; 40 | } 41 | 42 | /** 43 | * Indent 44 | */ 45 | indent() { 46 | this.indentations.push(this.indentString); 47 | } 48 | 49 | /** 50 | * Outdent 51 | */ 52 | outdent() { 53 | this.indentations.splice(this.indentations.length - 1, 1); 54 | } 55 | 56 | /** 57 | * Write a line 58 | * @param {string} line 59 | */ 60 | writeLine(line) { 61 | if (line) { 62 | this.lines.push(this.indentations.join("") + line); 63 | } else { 64 | this.lines.push(""); 65 | } 66 | } 67 | 68 | /** 69 | * Return as all string data 70 | * @return {string} 71 | */ 72 | getData() { 73 | return this.lines.join("\n"); 74 | } 75 | } 76 | 77 | exports.CodeWriter = CodeWriter; 78 | -------------------------------------------------------------------------------- /grammar/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | jison "cpp.jison" "cpp.jisonlex" -t -p lalr > jisonOutput.txt 4 | -------------------------------------------------------------------------------- /grammar/cpp.jison: -------------------------------------------------------------------------------- 1 | 2 | %token IDENTIFIER 3 | 4 | %token ABSTRACT AS BOOL BREAK CASE CATCH CHAR CHECKED CLASS CONST CONTINUE DECIMAL DEFAULT DELEGATE DO DOUBLE ELSE ENUM EXPLICIT EXTERN FALSE FINALLY FIXED FLOAT FOR FOREACH GOTO IF IMPLICIT INT INTERFACE INTERNAL LONG NAMESPACE NEW NULL OPERATOR OVERRIDE PARAMS PRIVATE PROTECTED PUBLIC READONLY RETURN SBYTE SHORT SIZEOF STACKALLOC STATIC STRUCT SWITCH THIS THROW TRUE TRY TYPEOF UINT ULONG UNCHECKED UNSAFE USHORT USING VIRTUAL VOID VOLATILE WHILE 5 | 6 | %token ASSEMBLY MODULE FIELD METHOD PARAM PROPERTY TYPE 7 | 8 | 9 | %token ADD REMOVE 10 | 11 | %token PARTIAL OP_DBLPTR 12 | 13 | %token TEMPLATE 14 | 15 | %token YIELD AWAIT WHERE 16 | 17 | %token DELETE FRIEND TYPEDEF AUTO REGISTER INLINE SIGNED UNSIGNED UNION ASM DOTS REF 18 | 19 | %token REAL_LITERAL 20 | %token INTEGER_LITERAL 21 | %token STRING_LITERAL 22 | %token CHARACTER_LITERAL 23 | 24 | %token OPEN_BRACE CLOSE_BRACE OPEN_BRACKET CLOSE_BRACKET OPEN_PARENS CLOSE_PARENS DOT COMMA COLON SEMICOLON PLUS MINUS STAR DIV PERCENT AMP BITWISE_OR CARET BANG TILDE ASSIGN LT GT INTERR DOUBLE_COLON OP_COALESCING OP_INC OP_DEC OP_AND OP_OR OP_PTR OP_EQ OP_NE OP_LE OP_GE OP_ADD_ASSIGNMENT OP_SUB_ASSIGNMENT OP_MULT_ASSIGNMENT OP_DIV_ASSIGNMENT OP_MOD_ASSIGNMENT OP_AND_ASSIGNMENT OP_OR_ASSIGNMENT OP_XOR_ASSIGNMENT OP_LEFT_SHIFT OP_LEFT_SHIFT_ASSIGNMENT RIGHT_SHIFT RIGHT_SHIFT_ASSIGNMENT 25 | 26 | 27 | %token EOF 28 | 29 | 30 | %start compilationUnit 31 | 32 | %% 33 | 34 | 35 | 36 | es 37 | : es e 38 | | e 39 | ; 40 | 41 | 42 | e 43 | : declaration-statement 44 | { 45 | console.log('declaration-statement '+$1); 46 | } 47 | 48 | | %empty 49 | { 50 | console.log('EMPTY'); 51 | } 52 | ; 53 | 54 | /* COLON IDENTIFIER */ 55 | COLON_IDENTIFIER 56 | : COLON_IDENTIFIER COLON IDENTIFIER_WITH_TEMPLATE 57 | | IDENTIFIER_WITH_TEMPLATE 58 | ; 59 | 60 | /* Boolearn Literals */ 61 | BOOLEAN_LITERAL 62 | : TRUE 63 | | FALSE 64 | ; 65 | 66 | string-list 67 | : string-list STRING_LITERAL 68 | | STRING_LITERAL 69 | ; 70 | 71 | literal 72 | : BOOLEAN_LITERAL 73 | { 74 | $$ = $1; 75 | } 76 | | REAL_LITERAL 77 | { 78 | $$ = $1; 79 | } 80 | | INTEGER_LITERAL 81 | { 82 | $$ = $1; 83 | } 84 | | STRING_LITERAL 85 | { 86 | $$ = $1; 87 | } 88 | | CHARACTER_LITERAL 89 | { 90 | $$ = $1; 91 | } 92 | | NULL 93 | { 94 | $$ = $1; 95 | } 96 | ; 97 | 98 | /* C.2.1 Basic concepts */ 99 | 100 | namespace-name 101 | : namespace-or-type-name 102 | { 103 | $$ = $1; 104 | } 105 | ; 106 | 107 | type-name 108 | : namespace-or-type-name 109 | { 110 | $$ = $1; 111 | } 112 | ; 113 | 114 | namespace-or-type-name 115 | : namespace-or-type-name DOUBLE_COLON STAR IDENTIFIER_WITH_KEYWORD 116 | { 117 | $$ = $1 + "::*" + $3; 118 | } 119 | | namespace-or-type-name DOUBLE_COLON IDENTIFIER_WITH_KEYWORD 120 | { 121 | $$ = $1 + "::" + $3; 122 | } 123 | | namespace-or-type-name DOT IDENTIFIER_WITH_KEYWORD 124 | { 125 | $$ = $1 + "." + $3; 126 | } 127 | | IDENTIFIER_WITH_KEYWORD 128 | { 129 | $$ = $1; 130 | } 131 | ; 132 | 133 | IDENTIFIER_WITH_TEMPLATE 134 | : IDENTIFIER TEMPLATE 135 | { 136 | 137 | $$ = { 138 | "name": $1 139 | }; 140 | 141 | $$["typeParameters"] = []; 142 | if ($2[0] === "<" && $2[$2.length-1] === ">") { 143 | var i, _temp, _param, _bounded; 144 | $2 = $2.substring(1, $2.length-1); 145 | _temp = $2.split(","); 146 | for (i = 0; i < _temp.length; i++) { 147 | _param = _temp[i].trim(); 148 | 149 | $$["typeParameters"].push({ 150 | "node": "TypeParameter", 151 | "name": _param 152 | }); 153 | 154 | } 155 | } 156 | } 157 | | IDENTIFIER 158 | { 159 | $$ = $1; 160 | } 161 | ; 162 | 163 | 164 | /* C.2.2 Types */ 165 | 166 | STARS 167 | : STARS STAR 168 | { 169 | $$ = $1 + "" + $2; 170 | } 171 | | STAR 172 | { 173 | $$ = $1; 174 | } 175 | ; 176 | 177 | type 178 | : type TEMPLATE 179 | { 180 | $$ = $1 + "" + $2; 181 | } 182 | | non-array-type AMP 183 | { 184 | $$ = $1 + "" + $2; 185 | } 186 | | array-type AMP 187 | { 188 | $$ = $1 + "" + $2; 189 | } 190 | | non-array-type STARS 191 | { 192 | $$ = $1 + "" + $2; 193 | } 194 | | array-type STARS 195 | { 196 | $$ = $1 + "" + $2; 197 | } 198 | | non-array-type OP_AND 199 | { 200 | $$ = $1 + "" + $2; 201 | } 202 | | array-type OP_AND 203 | { 204 | $$ = $1 + "" + $2; 205 | } 206 | | non-array-type CARET 207 | { 208 | $$ = $1 + "" + $2; 209 | } 210 | | array-type CARET 211 | { 212 | $$ = $1 + "" + $2; 213 | } 214 | | non-array-type 215 | { 216 | $$ = $1; 217 | } 218 | | array-type 219 | { 220 | $$ = $1; 221 | } 222 | | type STAR AMP 223 | { 224 | $$ = $1 + "*&"; 225 | } 226 | | TYPEDEF 227 | { 228 | $$ = $1; 229 | } 230 | | UNSIGNED type 231 | { 232 | $$ = $1 + " "+ $2; 233 | } 234 | | UNSIGNED 235 | { 236 | $$ = $1; 237 | } 238 | | INLINE 239 | { 240 | $$ = $1; 241 | } 242 | | INLINE STRUCT type 243 | { 244 | $$ = "inline struct "+$3; 245 | } 246 | | type CONST STAR 247 | { 248 | $$ = $1 + " const*"; 249 | } 250 | | type CONST 251 | { 252 | $$ + $1 + " const"; 253 | } 254 | | CONST type 255 | { 256 | $$ = "const "+$2; 257 | } 258 | | STATIC type 259 | { 260 | $$ = "static "+$2; 261 | } 262 | | VOLATILE type 263 | { 264 | $$ = "volatile "+ $2; 265 | } 266 | | VIRTUAL type 267 | { 268 | $$ = "virtual "+ $2; 269 | } 270 | | type DOUBLE_COLON STAR type 271 | { 272 | $$ = $1 + "::*"+$4; 273 | } 274 | | type DOUBLE_COLON type 275 | { 276 | $$ = $1 + "::" + $3; 277 | } 278 | | FRIEND CLASS 279 | { 280 | $$ = "friend class"; 281 | } 282 | | FRIEND type 283 | { 284 | $$ = "friend "+ $2; 285 | } 286 | ; 287 | 288 | type-with-interr 289 | : type 290 | { 291 | $$ = $1; 292 | } 293 | ; 294 | 295 | non-array-type 296 | : type-name 297 | { 298 | $$ = $1; 299 | } 300 | | SBYTE 301 | { 302 | $$ = $1; 303 | } 304 | | SHORT 305 | { 306 | $$ = $1; 307 | } 308 | | USHORT 309 | { 310 | $$ = $1; 311 | } 312 | | UINT 313 | { 314 | $$ = $1; 315 | } 316 | | LONG 317 | { 318 | $$ = $1; 319 | } 320 | | ULONG 321 | { 322 | $$ = $1; 323 | } 324 | | CHAR 325 | { 326 | $$ = $1; 327 | } 328 | | FLOAT 329 | { 330 | $$ = $1; 331 | } 332 | | DOUBLE 333 | { 334 | $$ = $1; 335 | } 336 | | DECIMAL 337 | { 338 | $$ = $1; 339 | } 340 | | BOOL 341 | { 342 | $$ = $1; 343 | } 344 | | VOID 345 | { 346 | $$ = $1; 347 | } 348 | | AUTO 349 | { 350 | $$ = $1; 351 | } 352 | | INT 353 | { 354 | $$ = $1; 355 | } 356 | | SHORT INT 357 | { 358 | $$ = $1 + " "+$2; 359 | } 360 | | LONG INT 361 | { 362 | $$ = $1 + " "+$2; 363 | } 364 | | LONG LONG 365 | { 366 | $$ = $1 + " "+$2; 367 | } 368 | | LONG DOUBLE 369 | { 370 | $$ = $1 + " "+$2; 371 | } 372 | | SIGNED INT 373 | { 374 | $$ = $1 + " "+$2; 375 | } 376 | | SIGNED CHAR 377 | { 378 | $$ = $1 + " "+$2; 379 | } 380 | | SIGNED LONG 381 | { 382 | $$ = $1 + " "+$2; 383 | } 384 | | SIGNED SHORT 385 | { 386 | $$ = $1 + " "+$2; 387 | } 388 | | SIGNED SHORT INT 389 | { 390 | $$ = $1 + " "+$2+ " "+$3;; 391 | } 392 | | SIGNED LONG INT 393 | { 394 | $$ = $1 + " "+$2+ " "+$3; 395 | } 396 | | SIGNED LONG LONG 397 | { 398 | $$ = $1 + " "+$2+ " "+$3;; 399 | } 400 | | SIGNED IDENTIFIER 401 | { 402 | $$ = $1 + " "+$2; 403 | } 404 | | UNSIGNED 405 | { 406 | $$ = $1; 407 | } 408 | | UNSIGNED INT 409 | { 410 | $$ = $1 + " "+$2; 411 | } 412 | | UNSIGNED CHAR 413 | { 414 | $$ = $1 + " "+$2; 415 | } 416 | | UNSIGNED LONG 417 | { 418 | $$ = $1 + " "+$2; 419 | } 420 | | UNSIGNED SHORT 421 | { 422 | $$ = $1 + " "+$2; 423 | } 424 | | UNSIGNED SHORT INT 425 | { 426 | $$ = $1 + " "+$2+ " "+$3;; 427 | } 428 | | UNSIGNED LONG INT 429 | { 430 | $$ = $1 + " "+$2+ " "+$3;; 431 | } 432 | | UNSIGNED LONG LONG 433 | { 434 | $$ = $1 + " "+$2+ " "+$3;; 435 | } 436 | ; 437 | 438 | array-type 439 | : type local-rank-specifiers 440 | { 441 | $$ = $1 + "" + $2; 442 | } 443 | ; 444 | 445 | 446 | rank-specifiers 447 | : rank-specifiers rank-specifier 448 | { 449 | $$ = $1 + "" + $2; 450 | } 451 | | rank-specifier 452 | { 453 | $$ = $1; 454 | } 455 | ; 456 | 457 | rank-specifier 458 | : OPEN_BRACKET dim-separators CLOSE_BRACKET 459 | { 460 | $$ = $1 + "" + $2 + "" + $3; 461 | } 462 | | OPEN_BRACKET CLOSE_BRACKET 463 | { 464 | $$ = $1 + "" + $2; 465 | } 466 | ; 467 | 468 | dim-separators 469 | : dim-separators COMMA 470 | { 471 | $$ = $1 + "" + $2; 472 | } 473 | | COMMA 474 | { 475 | $$ = $1; 476 | } 477 | ; 478 | 479 | 480 | /* C.2.3 Variables */ 481 | variable-reference 482 | : expression 483 | { 484 | $$ = $1; 485 | } 486 | ; 487 | 488 | 489 | 490 | /* C.2.4 Expressions */ 491 | argument-list 492 | : argument-list COLON argument 493 | { 494 | $$ = $1 + "" + $2 + "" + $3; 495 | } 496 | | argument-list COMMA STAR argument 497 | { 498 | $$ = $1 + ", *" + $4; 499 | } 500 | | argument-list COMMA argument 501 | { 502 | $$ = $1 + "" + $2 + "" + $3; 503 | } 504 | | argument 505 | { 506 | $$ = $1; 507 | } 508 | ; 509 | 510 | argument 511 | : CONST STRUCT expression 512 | { 513 | $$ = "const struct "+$3; 514 | } 515 | | STRUCT expression 516 | { 517 | $$ = "struct "+$2; 518 | } 519 | | expression 520 | { 521 | $$ = $1; 522 | } 523 | | argument local-rank-specifiers 524 | { 525 | $$ = $1 + $2; 526 | } 527 | | type 528 | { 529 | $$ = $1; 530 | } 531 | ; 532 | 533 | 534 | primary-expression 535 | : primary-no-array-creation-expression 536 | { 537 | $$ = $1; 538 | } 539 | | array-creation-expression 540 | { 541 | $$ = $1; 542 | } 543 | ; 544 | 545 | primary-no-array-creation-expression 546 | : lambda-expression 547 | { 548 | $$ = $1; 549 | } 550 | | cast-expression 551 | { 552 | $$ = $1; 553 | } 554 | | parenthesized-expression 555 | { 556 | $$ = $1; 557 | } 558 | | double-colon-access 559 | { 560 | $$ = $1; 561 | } 562 | | member-access 563 | { 564 | $$ = $1; 565 | } 566 | | invocation-expressions 567 | { 568 | $$ = $1; 569 | } 570 | | this-access 571 | { 572 | $$ = $1; 573 | } 574 | | post-increment-expression 575 | { 576 | $$ = $1; 577 | } 578 | | post-decrement-expression 579 | { 580 | $$ = $1; 581 | } 582 | | object-creation-expression 583 | { 584 | $$ = $1; 585 | } 586 | | typeof-expression 587 | { 588 | $$ = $1; 589 | } 590 | | sizeof-expression 591 | { 592 | $$ = $1; 593 | } 594 | | checked-expression 595 | { 596 | $$ = $1; 597 | } 598 | | unchecked-expression 599 | { 600 | $$ = $1; 601 | } 602 | | IDENTIFIER_WITH_KEYWORD OP_DBLPTR expression 603 | { 604 | $$ = $1 + "" + $2 + "" + $3; 605 | } 606 | | IDENTIFIER_WITH_KEYWORD OP_DBLPTR block 607 | { 608 | $$ = $1 + "" + $2 + "" + $3; 609 | } 610 | | DELEGATE block 611 | { 612 | $$ = $1 + "" + $2; 613 | } 614 | | delegate-expression 615 | { 616 | $$ = $1; 617 | } 618 | | deallocation-expression 619 | { 620 | $$ = $1; 621 | } 622 | | literal 623 | { 624 | $$ = $1; 625 | } 626 | | IDENTIFIER_WITH_KEYWORD 627 | { 628 | $$ = $1; 629 | } 630 | | DOUBLE_COLON STAR IDENTIFIER_WITH_KEYWORD 631 | { 632 | $$ = "::*" + $3; 633 | } 634 | | DOUBLE_COLON IDENTIFIER_WITH_KEYWORD 635 | { 636 | $$ = "::" + $2; 637 | } 638 | | element-access 639 | { 640 | $$ = $1; 641 | } 642 | ; 643 | 644 | 645 | 646 | type-expression-list 647 | : type-expression-list COMMA type expression 648 | { 649 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 650 | } 651 | | type expression 652 | { 653 | $$ = $1 + "" + $2; 654 | } 655 | ; 656 | 657 | dbl-expression-list 658 | : dbl-expression-list COMMA expression expression 659 | { 660 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 661 | } 662 | | expression expression 663 | { 664 | $$ = $1 + "" + $2; 665 | } 666 | ; 667 | 668 | lambda-expression 669 | : lambda-introducer lambda-declarator OP_PTR type block 670 | | lambda-introducer lambda-declarator OP_PTR block 671 | | lambda-introducer lambda-declarator block 672 | | lambda-introducer block 673 | | lambda-introducer 674 | ; 675 | 676 | lambda-introducer 677 | : OPEN_BRACKET lambda-capture CLOSE_BRACKET 678 | | OPEN_BRACKET expression-list CLOSE_BRACKET 679 | | OPEN_BRACKET dim-separators CLOSE_BRACKET 680 | | OPEN_BRACKET CLOSE_BRACKET 681 | ; 682 | 683 | lambda-capture 684 | : capture-default 685 | | capture-list 686 | | capture-default COMMA capture-list 687 | ; 688 | 689 | capture-default 690 | : AMP 691 | | ASSIGN 692 | ; 693 | 694 | capture-list 695 | : capture-list COMMA capture 696 | | capture 697 | ; 698 | 699 | capture 700 | : THIS 701 | | AMP IDENTIFIER_WITH_KEYWORD 702 | | IDENTIFIER_WITH_KEYWORD 703 | ; 704 | 705 | lambda-declarator 706 | : OPEN_PARENS formal-parameter-list CLOSE_PARENS 707 | | OPEN_PARENS CLOSE_PARENS 708 | ; 709 | 710 | delegate-expression 711 | : DELEGATE OPEN_PARENS formal-parameter-list CLOSE_PARENS block 712 | { 713 | $$ = $1 + "" + $2 + "" + $3 + "" + $4 + "" + $5; 714 | } 715 | | DELEGATE OPEN_PARENS CLOSE_PARENS block 716 | { 717 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 718 | } 719 | ; 720 | 721 | 722 | 723 | cast-expression 724 | : OPEN_PARENS STRUCT expression CLOSE_PARENS expression 725 | { 726 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 727 | } 728 | | OPEN_PARENS STRUCT type-with-interr CLOSE_PARENS expression 729 | { 730 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 731 | } 732 | | OPEN_PARENS expression CLOSE_PARENS expression 733 | { 734 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 735 | } 736 | | OPEN_PARENS type-with-interr CLOSE_PARENS expression 737 | { 738 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 739 | } 740 | | OPEN_PARENS expression-list CLOSE_PARENS expression 741 | { 742 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 743 | } 744 | | OPEN_PARENS expression-list CLOSE_PARENS 745 | { 746 | $$ = $1 + "" + $2 + "" +$3 ; 747 | } 748 | | type cast-expression 749 | { 750 | $$ = $1 + "" + $2; 751 | } 752 | ; 753 | 754 | 755 | parenthesized-expression 756 | : OPEN_PARENS expression CLOSE_PARENS 757 | { 758 | $$ = $1 + "" + $2 + "" + $3; 759 | } 760 | ; 761 | 762 | double-colon-access 763 | : IDENTIFIER_WITH_TEMPLATE DOUBLE_COLON primary-expression 764 | { 765 | $$ = $1 + "" + $2 + "" + $3; 766 | } 767 | | IDENTIFIER_WITH_TEMPLATE DOUBLE_COLON member-access 768 | { 769 | $$ = $1 + "" + $2 + "" + $3; 770 | } 771 | ; 772 | 773 | member-access 774 | : invocation-expressions DOT IDENTIFIER_WITH_KEYWORD 775 | { 776 | $$ = $1 + "" + $2 + "" + $3; 777 | } 778 | | primary-expression DOT IDENTIFIER_WITH_KEYWORD 779 | { 780 | $$ = $1 + "" + $2 + "" + $3; 781 | } 782 | | type DOT IDENTIFIER_WITH_KEYWORD 783 | { 784 | $$ = $1 + "" + $2 + "" + $3; 785 | } 786 | | invocation-expressions ptr-with-star IDENTIFIER_WITH_KEYWORD 787 | { 788 | $$ = $1 + "" + $2 + "" + $3; 789 | } 790 | | primary-expression ptr-with-star IDENTIFIER_WITH_KEYWORD 791 | { 792 | $$ = $1 + "" + $2 + "" + $3; 793 | } 794 | | type ptr-with-star IDENTIFIER_WITH_KEYWORD 795 | { 796 | $$ = $1 + "" + $2 + "" + $3; 797 | } 798 | 799 | ; 800 | 801 | ptr-with-star 802 | : OP_PTR STAR 803 | { 804 | $$ = $1 + ""+ $2; 805 | } 806 | | OP_PTR 807 | { 808 | $$ = $1; 809 | } 810 | ; 811 | 812 | 813 | 814 | invocation-expression 815 | : DOUBLE_COLON invocation-expression 816 | { 817 | $$ = $1 + "" +$2; 818 | } 819 | | primary-expression DOUBLE_COLON invocation-expression 820 | { 821 | $$ = $1 + "" + $2 + "" + $3; 822 | } 823 | | primary-expression OPEN_PARENS type-name CLOSE_PARENS 824 | { 825 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 826 | } 827 | | primary-expression OPEN_PARENS type CLOSE_PARENS 828 | { 829 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 830 | } 831 | | primary-expression OPEN_PARENS argument-list CLOSE_PARENS 832 | { 833 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 834 | } 835 | | primary-expression OPEN_PARENS CLOSE_PARENS 836 | { 837 | $$ = $1 + "" + $2 + "" + $3; 838 | } 839 | | member-name-with-double-colon OPEN_PARENS type-name CLOSE_PARENS 840 | { 841 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 842 | } 843 | | member-name-with-double-colon OPEN_PARENS type CLOSE_PARENS 844 | { 845 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 846 | } 847 | | member-name-with-double-colon OPEN_PARENS argument-list CLOSE_PARENS 848 | { 849 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 850 | } 851 | | member-name-with-double-colon OPEN_PARENS CLOSE_PARENS 852 | { 853 | $$ = $1 + "" + $2 + "" + $3; 854 | } 855 | | invocation-expression assignment-operator variable-initializer 856 | { 857 | $$ = $1 + "" + $2 + "" + $3; 858 | } 859 | ; 860 | 861 | element-access 862 | : primary-no-array-creation-expression OPEN_BRACKET expression-list CLOSE_BRACKET 863 | { 864 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 865 | } 866 | | primary-no-array-creation-expression OPEN_BRACKET dim-separators CLOSE_BRACKET 867 | { 868 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 869 | } 870 | | primary-no-array-creation-expression OPEN_BRACKET CLOSE_BRACKET 871 | { 872 | $$ = $1 + "" + $2 + "" + $3; 873 | } 874 | ; 875 | 876 | expression-list 877 | : STRUCT expression 878 | { 879 | $$ = $1 + "" + $2; 880 | } 881 | | expression 882 | { 883 | $$ = $1; 884 | } 885 | | expression-list COMMA expression 886 | { 887 | $$ = $1 + "" + $2 + "" + $3; 888 | } 889 | ; 890 | 891 | this-access 892 | : THIS 893 | { 894 | $$ = $1; 895 | } 896 | ; 897 | 898 | 899 | 900 | post-increment-expression 901 | : primary-expression OP_INC 902 | { 903 | $$ = $1 + "" + $2; 904 | } 905 | ; 906 | 907 | post-decrement-expression 908 | : primary-expression OP_DEC 909 | { 910 | $$ = $1 + "" + $2; 911 | } 912 | ; 913 | 914 | type-with-identifier 915 | : OPEN_PARENS type-with-identifier CLOSE_PARENS type-with-identifier 916 | { 917 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 918 | } 919 | | OPEN_PARENS type-with-identifier CLOSE_PARENS 920 | { 921 | $$ = $1 + "" + $2 + "" + $3; 922 | } 923 | | IDENTIFIER TEMPLATE 924 | { 925 | $$ = $1 + "" + $2; 926 | } 927 | | non-array-type 928 | { 929 | $$ = $1; 930 | } 931 | ; 932 | 933 | new-unsigned 934 | : NEW UNSIGNED 935 | { 936 | $$ = $1 + " " + $2; 937 | } 938 | | NEW STRUCT 939 | { 940 | $$ = $1 + " " + $2; 941 | } 942 | | REF NEW 943 | { 944 | $$ = $1 + " " + $2; 945 | } 946 | | NEW 947 | { 948 | $$ = $1; 949 | } 950 | ; 951 | 952 | object-creation-expression 953 | : new-unsigned type-with-identifier OPEN_PARENS argument-list CLOSE_PARENS invocation-expressions IDENTIFIER_WITH_DOT block-expression-with-brace 954 | { 955 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6 + "" + $7 + "" + $8; 956 | } 957 | | new-unsigned type-with-identifier OPEN_PARENS argument-list CLOSE_PARENS invocation-expressions IDENTIFIER_WITH_DOT 958 | { 959 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6 + "" + $7; 960 | } 961 | | new-unsigned type-with-identifier OPEN_PARENS CLOSE_PARENS invocation-expressions IDENTIFIER_WITH_DOT block-expression-with-brace 962 | { 963 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6 + "" + $7; 964 | } 965 | | new-unsigned type-with-identifier OPEN_PARENS CLOSE_PARENS invocation-expressions IDENTIFIER_WITH_DOT 966 | { 967 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6; 968 | } 969 | | new-unsigned type-with-identifier OPEN_PARENS CLOSE_PARENS block-expression-with-brace 970 | { 971 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5; 972 | } 973 | | new-unsigned type-with-identifier block-expression-with-brace 974 | { 975 | $$ = $1 + " " + $2 + "" + $3; 976 | } 977 | | new-unsigned non-array-type STAR rank-specifiers 978 | { 979 | $$ = $1 + " " + $2 + "" + $3 + "" + $4; 980 | } 981 | | new-unsigned non-array-type STAR rank-specifiers block-expression-with-brace 982 | { 983 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5; 984 | } 985 | | new-unsigned non-array-type rank-specifiers 986 | { 987 | $$ = $1 + " " + $2 + "" + $3 ; 988 | } 989 | | new-unsigned non-array-type rank-specifiers block-expression-with-brace 990 | { 991 | $$ = $1 + " " + $2 + "" + $3 + "" + $4; 992 | } 993 | | new-unsigned non-array-type STAR OPEN_BRACKET argument-list CLOSE_BRACKET block-expression-with-brace 994 | { 995 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6 + "" + $7; 996 | } 997 | | new-unsigned non-array-type STAR OPEN_BRACKET argument-list CLOSE_BRACKET 998 | { 999 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6; 1000 | } 1001 | | new-unsigned non-array-type OPEN_BRACKET argument-list CLOSE_BRACKET block-expression-with-brace 1002 | { 1003 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6; 1004 | } 1005 | | new-unsigned non-array-type OPEN_BRACKET argument-list CLOSE_BRACKET 1006 | { 1007 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5; 1008 | } 1009 | | new-unsigned type-with-identifier STAR rank-specifiers block-expression-with-brace 1010 | { 1011 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5; 1012 | } 1013 | | new-unsigned type-with-identifier STAR OPEN_BRACKET argument-list CLOSE_BRACKET block-expression-with-brace 1014 | { 1015 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6 + "" + $7; 1016 | } 1017 | | new-unsigned type-with-identifier STAR OPEN_BRACKET argument-list CLOSE_BRACKET 1018 | { 1019 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6; 1020 | } 1021 | 1022 | 1023 | | new-unsigned type-with-identifier rank-specifiers block-expression-with-brace 1024 | { 1025 | $$ = $1 + " " + $2 + "" + $3 + "" + $4; 1026 | } 1027 | | new-unsigned type-with-identifier OPEN_BRACKET argument-list CLOSE_BRACKET block-expression-with-brace 1028 | { 1029 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6; 1030 | } 1031 | | new-unsigned type-with-identifier OPEN_BRACKET argument-list CLOSE_BRACKET 1032 | { 1033 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5; 1034 | } 1035 | | new-unsigned type-with-identifier 1036 | { 1037 | $$ = $1 + " " + $2; 1038 | } 1039 | | new-unsigned STAR rank-specifiers block-expression-with-brace 1040 | { 1041 | $$ = $1 + " " + $2 + "" + $3; 1042 | } 1043 | | new-unsigned STAR rank-specifiers 1044 | { 1045 | $$ = $1 + " " + $2; 1046 | } 1047 | | new-unsigned rank-specifiers block-expression-with-brace 1048 | { 1049 | $$ = $1 + " " + $2 + "" + $3; 1050 | } 1051 | | new-unsigned rank-specifiers 1052 | { 1053 | $$ = $1 + " " + $2; 1054 | } 1055 | | new-unsigned block-expression-with-brace 1056 | { 1057 | $$ = $1 + " " + $2; 1058 | } 1059 | ; 1060 | 1061 | IDENTIFIER_WITH_DOT 1062 | : DOT IDENTIFIER_WITH_KEYWORD 1063 | { 1064 | $$ = $1 + "" + $2; 1065 | } 1066 | | %empty 1067 | ; 1068 | 1069 | argument-list-with-braces 1070 | : argument-list-with-braces COMMA argument-list-with-brace 1071 | { 1072 | $$ = $1 + "" + $2 + "" + $3; 1073 | } 1074 | | argument-list-with-brace 1075 | { 1076 | $$ = $1; 1077 | } 1078 | ; 1079 | 1080 | argument-list-with-brace 1081 | : OPEN_BRACE argument-list COMMA CLOSE_BRACE 1082 | { 1083 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 1084 | } 1085 | | OPEN_BRACE argument-list CLOSE_BRACE 1086 | { 1087 | $$ = $1 + "" + $2 + "" + $3; 1088 | } 1089 | | OPEN_BRACE CLOSE_BRACE 1090 | { 1091 | $$ = $1 + "" + $2; 1092 | } 1093 | ; 1094 | 1095 | 1096 | 1097 | invocation-expressions 1098 | : invocation-expressions DOT invocation-expression 1099 | { 1100 | $$ = $1 + "" + $2 + "" + $3; 1101 | } 1102 | | invocation-expression 1103 | { 1104 | $$ = $1; 1105 | } 1106 | | %empty 1107 | ; 1108 | 1109 | array-creation-expression 1110 | : STACKALLOC non-array-type OPEN_BRACKET CLOSE_BRACKET argument-list-with-brace 1111 | { 1112 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6; 1113 | } 1114 | | STACKALLOC non-array-type OPEN_BRACKET expression-list CLOSE_BRACKET 1115 | { 1116 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5; 1117 | } 1118 | | STACKALLOC non-array-type OPEN_BRACKET expression-list CLOSE_BRACKET rank-specifiers 1119 | { 1120 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6; 1121 | } 1122 | | STACKALLOC non-array-type OPEN_BRACKET expression-list CLOSE_BRACKET array-initializer 1123 | { 1124 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6; 1125 | } 1126 | | STACKALLOC non-array-type OPEN_BRACKET expression-list CLOSE_BRACKET rank-specifiers array-initializer 1127 | { 1128 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6 + "" + $7; 1129 | } 1130 | | STACKALLOC array-type array-initializer 1131 | { 1132 | $$ = $1 + " " + $2 + "" + $3; 1133 | } 1134 | ; 1135 | 1136 | delegate-creation-expression 1137 | : NEW type OPEN_PARENS argument-list CLOSE_PARENS block-expression-with-brace 1138 | { 1139 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6; 1140 | } 1141 | | NEW type OPEN_PARENS argument-list CLOSE_PARENS 1142 | { 1143 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5; 1144 | } 1145 | | NEW type OPEN_PARENS CLOSE_PARENS block-expression-with-brace 1146 | { 1147 | $$ = $1 + " " + $2 + "" + $3 + "" + $4 + "" + $5; 1148 | } 1149 | | NEW type OPEN_PARENS CLOSE_PARENS 1150 | { 1151 | $$ = $1 + " " + $2 + "" + $3 + "" + $4; 1152 | } 1153 | | NEW type block-expression-with-brace 1154 | { 1155 | $$ = $1 + " " + $2 + "" + $3; 1156 | } 1157 | | REF delegate-creation-expression 1158 | { 1159 | $$ = $1 + " "+ $2; 1160 | } 1161 | ; 1162 | 1163 | 1164 | typeof-expression 1165 | : TYPEOF OPEN_PARENS type-with-interr CLOSE_PARENS 1166 | { 1167 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 1168 | } 1169 | ; 1170 | 1171 | sizeof-expression 1172 | : SIZEOF OPEN_PARENS STARS type-with-interr CLOSE_PARENS 1173 | { 1174 | $$ = $1 + "" + $2 + "" + $3 + "" + $4 + "" + $5; 1175 | } 1176 | | SIZEOF OPEN_PARENS STRUCT type-with-interr CLOSE_PARENS 1177 | { 1178 | $$ = $1 + "" + $2 + "" + $3 + "" + $4 + "" + $5; 1179 | } 1180 | | SIZEOF OPEN_PARENS type-with-interr CLOSE_PARENS 1181 | { 1182 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 1183 | } 1184 | | SIZEOF type-with-interr 1185 | { 1186 | $$ = $1 + "" + $2 ; 1187 | } 1188 | ; 1189 | 1190 | 1191 | checked-expression 1192 | : CHECKED OPEN_PARENS expression CLOSE_PARENS 1193 | { 1194 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 1195 | } 1196 | ; 1197 | 1198 | unchecked-expression 1199 | : UNCHECKED OPEN_PARENS expression CLOSE_PARENS 1200 | { 1201 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 1202 | } 1203 | ; 1204 | 1205 | unary-expression 1206 | : pre-increment-expression 1207 | { 1208 | $$ = $1; 1209 | } 1210 | | pre-decrement-expression 1211 | { 1212 | $$ = $1; 1213 | } 1214 | | PLUS unary-expression 1215 | { 1216 | $$ = $1 + "" + $2; 1217 | } 1218 | | OP_COALESCING unary-expression 1219 | { 1220 | $$ = $1 + "" + $2; 1221 | } 1222 | | MINUS unary-expression 1223 | { 1224 | $$ = $1 + "" + $2; 1225 | } 1226 | | BANG unary-expression 1227 | { 1228 | $$ = $1 + "" + $2; 1229 | } 1230 | | TILDE unary-expression 1231 | { 1232 | $$ = $1 + "" + $2; 1233 | } 1234 | | STAR unary-expression 1235 | { 1236 | $$ = $1 + "" + $2; 1237 | } 1238 | | CARET unary-expression 1239 | { 1240 | $$ = $1 + "" + $2; 1241 | } 1242 | | primary-expression 1243 | { 1244 | $$ = $1; 1245 | } 1246 | ; 1247 | 1248 | unary-or-cast-expression 1249 | : unary-expression 1250 | { 1251 | $$ = $1; 1252 | } 1253 | | OPEN_PARENS type-name CLOSE_PARENS cast-expression 1254 | { 1255 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 1256 | } 1257 | ; 1258 | 1259 | deallocation-expression 1260 | : DOUBLE_COLON DELETE unary-or-cast-expression 1261 | { 1262 | $$ = $1 + "" + $2 + "" + $3; 1263 | } 1264 | | DELETE unary-or-cast-expression 1265 | { 1266 | $$ = $1 + "" + $2; 1267 | } 1268 | | DOUBLE_COLON DELETE OPEN_BRACKET CLOSE_BRACKET unary-or-cast-expression 1269 | { 1270 | $$ = $1 + "" + $2 + "" + $3 + "" + $4 + "" + $5; 1271 | } 1272 | | DELETE OPEN_BRACKET CLOSE_BRACKET unary-or-cast-expression 1273 | { 1274 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 1275 | } 1276 | ; 1277 | 1278 | pre-increment-expression 1279 | : OP_INC unary-expression 1280 | { 1281 | $$ = $1 + "" + $2; 1282 | } 1283 | ; 1284 | 1285 | pre-decrement-expression 1286 | : OP_DEC unary-expression 1287 | { 1288 | $$ = $1 + "" + $2; 1289 | } 1290 | ; 1291 | 1292 | expression-with-comma 1293 | : expression-with-comma COMMA expression 1294 | { 1295 | $$ = $1 + "" + $3 + "" + $2; 1296 | } 1297 | | expression 1298 | { 1299 | $$ = $1; 1300 | } 1301 | ; 1302 | 1303 | 1304 | 1305 | 1306 | multiplicative-expression 1307 | : unary-expression 1308 | { 1309 | $$ = $1; 1310 | } 1311 | | multiplicative-expression STAR unary-expression 1312 | { 1313 | $$ = $1 + "" + $2 + "" + $3; 1314 | } 1315 | | multiplicative-expression DIV unary-expression 1316 | { 1317 | $$ = $1 + "" + $2 + "" + $3; 1318 | } 1319 | | multiplicative-expression PERCENT unary-expression 1320 | { 1321 | $$ = $1 + "" + $2 + "" + $3; 1322 | } 1323 | ; 1324 | 1325 | additive-expression 1326 | : multiplicative-expression 1327 | { 1328 | $$ = $1; 1329 | } 1330 | | additive-expression PLUS multiplicative-expression 1331 | { 1332 | $$ = $1 + "" + $2 + "" + $3; 1333 | } 1334 | | additive-expression OP_PTR multiplicative-expression 1335 | { 1336 | $$ = $1 + "" + $2 + "" + $3; 1337 | } 1338 | | additive-expression OP_COALESCING multiplicative-expression 1339 | { 1340 | $$ = $1 + "" + $2 + "" + $3; 1341 | } 1342 | | additive-expression MINUS multiplicative-expression 1343 | { 1344 | $$ = $1 + "" + $2 + "" + $3; 1345 | } 1346 | ; 1347 | 1348 | shift-expression 1349 | : additive-expression 1350 | { 1351 | $$ = $1; 1352 | } 1353 | | shift-expression OP_LEFT_SHIFT additive-expression 1354 | { 1355 | $$ = $1 + "" + $2 + "" + $3; 1356 | } 1357 | | shift-expression RIGHT_SHIFT additive-expression 1358 | { 1359 | $$ = $1 + "" + $2 + "" + $3; 1360 | } 1361 | ; 1362 | 1363 | relational-expression 1364 | : shift-expression 1365 | { 1366 | $$ = $1; 1367 | } 1368 | | relational-expression LT shift-expression 1369 | { 1370 | $$ = $1 + "" + $2 + "" + $3; 1371 | } 1372 | | relational-expression GT shift-expression 1373 | { 1374 | $$ = $1 + "" + $2 + "" + $3; 1375 | } 1376 | | relational-expression OP_LE shift-expression 1377 | { 1378 | $$ = $1 + "" + $2 + "" + $3; 1379 | } 1380 | | relational-expression OP_GE shift-expression 1381 | { 1382 | $$ = $1 + "" + $2 + "" + $3; 1383 | } 1384 | | relational-expression OP_COALESCING shift-expression 1385 | { 1386 | $$ = $1 + "" + $2 + "" + $3; 1387 | } 1388 | | relational-expression AS type 1389 | { 1390 | $$ = $1 + "" + $2 + "" + $3; 1391 | } 1392 | ; 1393 | 1394 | equality-expression 1395 | : relational-expression 1396 | { 1397 | $$ = $1; 1398 | } 1399 | | equality-expression OP_EQ relational-expression 1400 | { 1401 | $$ = $1 + "" + $2 + "" + $3; 1402 | } 1403 | | equality-expression OP_NE relational-expression 1404 | { 1405 | $$ = $1 + "" + $2 + "" + $3; 1406 | } 1407 | ; 1408 | 1409 | and-expression 1410 | : equality-expression 1411 | { 1412 | $$ = $1; 1413 | } 1414 | | and-expression AMP equality-expression 1415 | { 1416 | $$ = $1 + "" + $2 + "" + $3; 1417 | } 1418 | ; 1419 | 1420 | exclusive-or-expression 1421 | : and-expression 1422 | { 1423 | $$ = $1; 1424 | } 1425 | | exclusive-or-expression CARET and-expression 1426 | { 1427 | $$ = $1 + "" + $2 + "" + $3; 1428 | } 1429 | ; 1430 | 1431 | inclusive-or-expression 1432 | : exclusive-or-expression 1433 | { 1434 | $$ = $1; 1435 | } 1436 | | inclusive-or-expression BITWISE_OR exclusive-or-expression 1437 | { 1438 | $$ = $1 + "" + $2 + "" + $3; 1439 | } 1440 | ; 1441 | 1442 | conditional-and-expression 1443 | : inclusive-or-expression 1444 | { 1445 | $$ = $1; 1446 | } 1447 | | conditional-and-expression OP_AND inclusive-or-expression 1448 | { 1449 | $$ = $1 + "" + $2 + "" + $3; 1450 | } 1451 | ; 1452 | 1453 | conditional-or-expression 1454 | : conditional-and-expression 1455 | { 1456 | $$ = $1; 1457 | } 1458 | | conditional-or-expression OP_OR conditional-and-expression 1459 | { 1460 | $$ = $1 + "" + $2 + "" + $3; 1461 | } 1462 | ; 1463 | 1464 | conditional-expression 1465 | : conditional-or-expression 1466 | { 1467 | $$ = $1; 1468 | } 1469 | | conditional-or-expression INTERR expression 1470 | { 1471 | $$ = $1 + "" + $2 + "" + $3; 1472 | } 1473 | | conditional-or-expression INTERR expression COLON expression 1474 | { 1475 | $$ = $1 + "" + $2 + "" + $3 + "" + $4 + "" + $5; 1476 | } 1477 | | conditional-or-expression INTERR OPEN_PARENS expression CLOSE_PARENS 1478 | { 1479 | $$ = $1 + "" + $2 + "" + $3 + "" + $4+ "" + $5; 1480 | } 1481 | | conditional-or-expression INTERR OPEN_PARENS expression CLOSE_PARENS COLON expression 1482 | { 1483 | $$ = $1 + "" + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6 + "" + $7; 1484 | } 1485 | | conditional-or-expression INTERR OPEN_PARENS expression CLOSE_PARENS COLON OPEN_PARENS expression CLOSE_PARENS 1486 | { 1487 | $$ = $1 + "" + $2 + "" + $3 + "" + $4 + "" + $5 + "" + $6 + "" + $7 + "" + $8 + "" + $9; 1488 | } 1489 | ; 1490 | 1491 | assignment 1492 | : unary-expression assignment-operator expression 1493 | { 1494 | $$ = $1 + "" + $2 + "" + $3; 1495 | } 1496 | | unary-expression assignment-operator block-expression-with-brace 1497 | { 1498 | $$ = $1 + "" + $2 + "" + $3; 1499 | } 1500 | ; 1501 | 1502 | block-expression 1503 | : block-expression-with-brace 1504 | { 1505 | $$ = $1; 1506 | } 1507 | | OPEN_BRACE expression-list CLOSE_BRACE 1508 | { 1509 | $$ = $1 + "" + $2 + "" + $3; 1510 | } 1511 | ; 1512 | 1513 | block-expression-list-unit 1514 | : block-expression-with-brace 1515 | { 1516 | $$ = $1; 1517 | } 1518 | | expression 1519 | { 1520 | $$ = $1; 1521 | } 1522 | ; 1523 | 1524 | block-expression-list 1525 | : block-expression-list COMMA block-expression-list-unit 1526 | { 1527 | $$ = $1 + "" + $2 + "" + $3; 1528 | } 1529 | | block-expression-list-unit 1530 | { 1531 | $$ = $1; 1532 | } 1533 | ; 1534 | 1535 | block-expression-with-brace 1536 | : OPEN_BRACE block-expression-list CLOSE_BRACE 1537 | { 1538 | $$ = $1 + "" + $2 + "" + $3; 1539 | } 1540 | ; 1541 | 1542 | 1543 | assignment-operator 1544 | : ASSIGN 1545 | { 1546 | $$ = $1; 1547 | } 1548 | | OP_ADD_ASSIGNMENT 1549 | { 1550 | $$ = $1; 1551 | } 1552 | | OP_SUB_ASSIGNMENT 1553 | { 1554 | $$ = $1; 1555 | } 1556 | | OP_MULT_ASSIGNMENT 1557 | { 1558 | $$ = $1; 1559 | } 1560 | | OP_DIV_ASSIGNMENT 1561 | { 1562 | $$ = $1; 1563 | } 1564 | | OP_MOD_ASSIGNMENT 1565 | { 1566 | $$ = $1; 1567 | } 1568 | | OP_AND_ASSIGNMENT 1569 | { 1570 | $$ = $1; 1571 | } 1572 | | OP_OR_ASSIGNMENT 1573 | { 1574 | $$ = $1; 1575 | } 1576 | | OP_XOR_ASSIGNMENT 1577 | { 1578 | $$ = $1; 1579 | } 1580 | | OP_LEFT_SHIFT_ASSIGNMENT 1581 | { 1582 | $$ = $1; 1583 | } 1584 | | RIGHT_SHIFT_ASSIGNMENT 1585 | { 1586 | $$ = $1; 1587 | } 1588 | ; 1589 | 1590 | expression 1591 | : conditional-expression 1592 | { 1593 | $$ = $1; 1594 | } 1595 | | assignment 1596 | { 1597 | $$ = $1; 1598 | } 1599 | ; 1600 | 1601 | constant-expression 1602 | : expression 1603 | { 1604 | $$ = $1; 1605 | } 1606 | ; 1607 | 1608 | boolean-expression 1609 | : expression 1610 | { 1611 | $$ = $1; 1612 | } 1613 | ; 1614 | 1615 | 1616 | 1617 | /* C.2.5 Statements */ 1618 | statement 1619 | : labeled-statement 1620 | { 1621 | $$ = $1; 1622 | } 1623 | | declaration-statement 1624 | { 1625 | $$ = $1; 1626 | } 1627 | | embedded-statement 1628 | { 1629 | $$ = $1; 1630 | } 1631 | | using-directive 1632 | { 1633 | $$ = $1; 1634 | } 1635 | ; 1636 | 1637 | 1638 | embedded-statement 1639 | : block 1640 | | empty-statement 1641 | | statement-expression block 1642 | | statement-expression SEMICOLON 1643 | | statement-expression STAR local-rank-specifiers ASSIGN variable-initializer SEMICOLON 1644 | | statement-expression STAR local-rank-specifiers SEMICOLON 1645 | | statement-expression STAR local-rank-specifiers COMMA local-variable-declarators SEMICOLON 1646 | | statement-expression local-rank-specifiers ASSIGN variable-initializer SEMICOLON 1647 | | statement-expression local-rank-specifiers SEMICOLON 1648 | | statement-expression local-rank-specifiers COMMA local-variable-declarators SEMICOLON 1649 | | selection-statement 1650 | | iteration-statement 1651 | | jump-statement 1652 | | try-statement 1653 | | checked-statement 1654 | | unchecked-statement 1655 | | using-statement 1656 | | unsafe-statement 1657 | | fixed-statement 1658 | | shift-expression SEMICOLON 1659 | | conditional-expression SEMICOLON 1660 | ; 1661 | 1662 | 1663 | fixed-statement 1664 | : modifiers FIXED OPEN_PARENS type local-variable-declarators CLOSE_PARENS embedded-statement 1665 | | FIXED OPEN_PARENS type local-variable-declarators CLOSE_PARENS embedded-statement 1666 | ; 1667 | 1668 | unsafe-statement 1669 | : UNSAFE block 1670 | ; 1671 | 1672 | block 1673 | : OPEN_BRACE CLOSE_BRACE 1674 | | OPEN_BRACE statement-list CLOSE_BRACE 1675 | ; 1676 | 1677 | statement-list 1678 | : statement 1679 | | statement-list statement 1680 | ; 1681 | 1682 | empty-statement 1683 | : SEMICOLON 1684 | ; 1685 | 1686 | labeled-statement 1687 | : IDENTIFIER_WITH_KEYWORD COLON switch-labels 1688 | | IDENTIFIER_WITH_KEYWORD COLON statement 1689 | ; 1690 | 1691 | declaration-statement 1692 | : local-variable-declaration SEMICOLON 1693 | | local-constant-declaration SEMICOLON 1694 | | local-variable-declaration block 1695 | | local-constant-declaration block 1696 | | local-variable-declaration 1697 | | local-constant-declaration 1698 | | class-declaration 1699 | ; 1700 | 1701 | local-variable-declaration 1702 | : STATIC CONST STRUCT struct-body identifier-list struct-bracket 1703 | | STATIC STRUCT type local-variable-declarators 1704 | | STRUCT OPEN_BRACE struct-member-list CLOSE_BRACE identifier-list struct-bracket 1705 | | STRUCT OPEN_BRACE CLOSE_BRACE identifier-list struct-bracket 1706 | | STRUCT type local-variable-declarators 1707 | | CONST STRUCT type local-variable-declarators 1708 | | ENUM OPEN_BRACE enum-member-declarations COMMA CLOSE_BRACE 1709 | | ENUM OPEN_BRACE enum-member-declarations CLOSE_BRACE 1710 | | ENUM type local-variable-declarators 1711 | | fixed-parameter-prefix type local-variable-declarators 1712 | | type local-variable-declarators 1713 | | primary-expression local-variable-declarators 1714 | ; 1715 | 1716 | local-variable-declarators 1717 | : local-variable-declarators COMMA STAR local-variable-declarator 1718 | | local-variable-declarators COMMA local-variable-declarator 1719 | | local-variable-declarator 1720 | ; 1721 | 1722 | local-rank-specifiers 1723 | : local-rank-specifiers local-rank-specifier 1724 | { 1725 | $$ = $1 + "" + $2; 1726 | } 1727 | | local-rank-specifier 1728 | { 1729 | $$ = $1; 1730 | } 1731 | ; 1732 | 1733 | local-rank-specifier 1734 | : OPEN_BRACKET expression-list CLOSE_BRACKET 1735 | | OPEN_BRACKET dim-separators CLOSE_BRACKET 1736 | | OPEN_BRACKET CLOSE_BRACKET 1737 | ; 1738 | 1739 | 1740 | local-variable 1741 | : STARS IDENTIFIER_WITH_KEYWORD 1742 | | OP_AND IDENTIFIER_WITH_KEYWORD 1743 | | AMP IDENTIFIER_WITH_KEYWORD 1744 | | CARET IDENTIFIER_WITH_KEYWORD 1745 | | IDENTIFIER_WITH_KEYWORD local-rank-specifiers 1746 | | IDENTIFIER_WITH_KEYWORD 1747 | | %empty 1748 | ; 1749 | 1750 | local-variable-declarator 1751 | : local-variable ASSIGN local-variable-initializer 1752 | | local-variable 1753 | ; 1754 | 1755 | local-variable-initializer 1756 | : expression 1757 | | array-initializer 1758 | ; 1759 | 1760 | local-constant-declaration 1761 | : type constant-declarators 1762 | ; 1763 | 1764 | constant-declarators 1765 | : constant-declarator 1766 | | constant-declarators COMMA constant-declarator 1767 | ; 1768 | 1769 | constant-declarator 1770 | : IDENTIFIER_WITH_TEMPLATE ASSIGN constant-expression 1771 | ; 1772 | 1773 | 1774 | 1775 | statement-expression 1776 | : object-creation-expression 1777 | | post-increment-expression 1778 | | post-decrement-expression 1779 | | pre-increment-expression 1780 | | pre-decrement-expression 1781 | | assignment 1782 | | invocation-expressions 1783 | ; 1784 | 1785 | selection-statement 1786 | : if-statement 1787 | | switch-statement 1788 | ; 1789 | 1790 | if-statement 1791 | : IF OPEN_PARENS boolean-expression CLOSE_PARENS embedded-or-statement 1792 | | IF OPEN_PARENS boolean-expression CLOSE_PARENS embedded-or-statement ELSE embedded-statement 1793 | | ELSE if-statement 1794 | ; 1795 | 1796 | boolean-expression 1797 | : expression 1798 | ; 1799 | 1800 | switch-statement 1801 | : SWITCH OPEN_PARENS expression CLOSE_PARENS switch-block 1802 | ; 1803 | 1804 | switch-block 1805 | : OPEN_BRACE CLOSE_BRACE 1806 | | OPEN_BRACE switch-sections CLOSE_BRACE 1807 | ; 1808 | 1809 | switch-sections 1810 | : switch-sections switch-section 1811 | | switch-section 1812 | ; 1813 | 1814 | switch-section 1815 | : switch-labels statement-list 1816 | ; 1817 | 1818 | switch-labels 1819 | : switch-labels switch-label 1820 | | switch-label 1821 | ; 1822 | 1823 | switch-label 1824 | : CASE constant-expression COLON 1825 | | DEFAULT COLON 1826 | ; 1827 | 1828 | iteration-statement 1829 | : while-statement 1830 | | do-statement 1831 | | for-statement 1832 | ; 1833 | 1834 | embedded-or-statement 1835 | : statement 1836 | | embedded-statement 1837 | ; 1838 | 1839 | while-statement 1840 | : WHILE OPEN_PARENS boolean-expression CLOSE_PARENS embedded-or-statement 1841 | ; 1842 | 1843 | do-statement 1844 | : DO embedded-or-statement WHILE OPEN_PARENS boolean-expression CLOSE_PARENS SEMICOLON 1845 | ; 1846 | 1847 | for-statement 1848 | : FOR OPEN_PARENS SEMICOLON SEMICOLON CLOSE_PARENS embedded-or-statement 1849 | | FOR OPEN_PARENS for-initializer SEMICOLON SEMICOLON CLOSE_PARENS embedded-or-statement 1850 | | FOR OPEN_PARENS SEMICOLON for-condition SEMICOLON CLOSE_PARENS embedded-or-statement 1851 | | FOR OPEN_PARENS SEMICOLON SEMICOLON for-iterator CLOSE_PARENS embedded-or-statement 1852 | | FOR OPEN_PARENS for-initializer SEMICOLON for-condition SEMICOLON CLOSE_PARENS embedded-or-statement 1853 | | FOR OPEN_PARENS for-initializer SEMICOLON SEMICOLON for-iterator CLOSE_PARENS embedded-or-statement 1854 | | FOR OPEN_PARENS SEMICOLON for-condition SEMICOLON for-iterator CLOSE_PARENS embedded-or-statement 1855 | | FOR OPEN_PARENS for-initializer SEMICOLON for-condition SEMICOLON for-iterator CLOSE_PARENS embedded-or-statement 1856 | | FOR OPEN_PARENS for-initializer COLON expression CLOSE_PARENS embedded-or-statement 1857 | ; 1858 | 1859 | for-initializer 1860 | : local-variable-declaration 1861 | | statement-expression-list 1862 | ; 1863 | 1864 | for-condition 1865 | : boolean-expression 1866 | ; 1867 | 1868 | for-iterator 1869 | : statement-expression-list 1870 | ; 1871 | 1872 | statement-expression-list 1873 | : statement-expression 1874 | | statement-expression-list COMMA STAR statement-expression 1875 | | statement-expression-list COMMA statement-expression 1876 | ; 1877 | 1878 | 1879 | jump-statement 1880 | : break-statement 1881 | | continue-statement 1882 | | goto-statement 1883 | | return-statement 1884 | | throw-statement 1885 | ; 1886 | 1887 | break-statement 1888 | : YIELD BREAK SEMICOLON 1889 | | BREAK SEMICOLON 1890 | ; 1891 | 1892 | continue-statement 1893 | : CONTINUE SEMICOLON 1894 | ; 1895 | 1896 | goto-statement 1897 | : GOTO IDENTIFIER_WITH_TEMPLATE SEMICOLON 1898 | | GOTO CASE constant-expression SEMICOLON 1899 | | GOTO DEFAULT SEMICOLON 1900 | ; 1901 | 1902 | return-statement 1903 | : YIELD RETURN block-expression-with-brace SEMICOLON 1904 | | YIELD RETURN expression SEMICOLON 1905 | | YIELD RETURN SEMICOLON 1906 | | RETURN block-expression-with-brace SEMICOLON 1907 | | RETURN SEMICOLON 1908 | | RETURN expression SEMICOLON 1909 | ; 1910 | 1911 | throw-statement 1912 | : THROW SEMICOLON 1913 | | THROW expression SEMICOLON 1914 | ; 1915 | 1916 | try-statement 1917 | : TRY block catch-clauses 1918 | | TRY block finally-clause 1919 | | TRY block catch-clauses finally-clause 1920 | ; 1921 | 1922 | catch-clauses 1923 | : specific-catch-clauses 1924 | | general-catch-clause 1925 | | specific-catch-clauses general-catch-clause 1926 | ; 1927 | 1928 | specific-catch-clauses 1929 | : specific-catch-clause 1930 | | specific-catch-clauses specific-catch-clause 1931 | ; 1932 | 1933 | specific-catch-clause 1934 | : CATCH OPEN_PARENS type CLOSE_PARENS block 1935 | | CATCH OPEN_PARENS type IDENTIFIER_WITH_TEMPLATE CLOSE_PARENS block 1936 | ; 1937 | 1938 | general-catch-clause 1939 | : CATCH block 1940 | ; 1941 | 1942 | finally-clause 1943 | : FINALLY block 1944 | ; 1945 | 1946 | checked-statement 1947 | : CHECKED block 1948 | ; 1949 | 1950 | unchecked-statement 1951 | : UNCHECKED block 1952 | ; 1953 | 1954 | 1955 | 1956 | using-statement 1957 | : USING OPEN_PARENS resource-acquisition CLOSE_PARENS embedded-or-statement 1958 | ; 1959 | 1960 | resource-acquisition 1961 | : local-variable-declaration 1962 | | expression 1963 | ; 1964 | 1965 | 1966 | 1967 | /* C.2.9 Arrays */ 1968 | 1969 | array-initializer 1970 | : OPEN_BRACE CLOSE_BRACE 1971 | | OPEN_BRACE variable-initializer-list CLOSE_BRACE 1972 | | OPEN_BRACE variable-initializer-list COMMA CLOSE_BRACE 1973 | ; 1974 | 1975 | variable-initializer-list 1976 | : variable-initializer 1977 | | variable-initializer-list COMMA STAR variable-initializer 1978 | | variable-initializer-list COMMA variable-initializer 1979 | ; 1980 | 1981 | variable-initializer 1982 | : expression 1983 | | array-initializer 1984 | ; 1985 | 1986 | 1987 | 1988 | 1989 | 1990 | /* C.2.11 Enums */ 1991 | enum-declaration 1992 | : enum-class enum-body 1993 | { 1994 | $$ = { 1995 | "node": "enum", 1996 | "body": $2 1997 | }; 1998 | } 1999 | | enum-class enum-body SEMICOLON 2000 | { 2001 | $$ = { 2002 | "node": "enum", 2003 | "body": $2 2004 | }; 2005 | } 2006 | | modifiers enum-class enum-body 2007 | { 2008 | $$ = { 2009 | "node": "enum", 2010 | "modifiers": $1, 2011 | "body": $3 2012 | }; 2013 | } 2014 | | modifiers enum-class enum-body SEMICOLON 2015 | { 2016 | $$ = { 2017 | "node": "enum", 2018 | "modifiers": $1, 2019 | "body": $3 2020 | }; 2021 | } 2022 | | enum-class member-name-with-double-colon SEMICOLON 2023 | { 2024 | $$ = { 2025 | "node": "enum", 2026 | "name": $2 2027 | }; 2028 | } 2029 | | enum-class member-name-with-double-colon enum-body 2030 | { 2031 | $$ = { 2032 | "node": "enum", 2033 | "name": $2, 2034 | "body": $3 2035 | }; 2036 | } 2037 | | modifiers enum-class member-name-with-double-colon enum-body 2038 | { 2039 | $$ = { 2040 | "node": "enum", 2041 | "modifiers": $1, 2042 | "name": $3, 2043 | "body": $4 2044 | }; 2045 | } 2046 | | enum-class member-name-with-double-colon enum-base enum-body 2047 | { 2048 | $$ = { 2049 | "node": "enum", 2050 | "name": $2, 2051 | "base": $3, 2052 | "body": $4 2053 | }; 2054 | } 2055 | | enum-class member-name-with-double-colon enum-body SEMICOLON 2056 | { 2057 | $$ = { 2058 | "node": "enum", 2059 | "name": $2, 2060 | "body": $3 2061 | }; 2062 | } 2063 | | modifiers enum-class member-name-with-double-colon enum-base enum-body 2064 | { 2065 | $$ = { 2066 | "node": "enum", 2067 | "modifiers": $1, 2068 | "name": $3, 2069 | "base": $4, 2070 | "body": $5 2071 | }; 2072 | } 2073 | | modifiers enum-class member-name-with-double-colon enum-body SEMICOLON 2074 | { 2075 | $$ = { 2076 | "node": "enum", 2077 | "modifiers": $1, 2078 | "name": $3, 2079 | "body": $4 2080 | }; 2081 | } 2082 | | enum-class member-name-with-double-colon enum-base enum-body SEMICOLON 2083 | { 2084 | $$ = { 2085 | "node": "enum", 2086 | "name": $2, 2087 | "base": $3, 2088 | "body": $4 2089 | }; 2090 | } 2091 | | modifiers enum-class member-name-with-double-colon enum-base enum-body SEMICOLON 2092 | { 2093 | $$ = { 2094 | "node": "enum", 2095 | "modifiers": $1, 2096 | "name": $3, 2097 | "base": $4, 2098 | "body": $5 2099 | }; 2100 | } 2101 | ; 2102 | 2103 | enum-class 2104 | : ENUM class-key 2105 | | ENUM 2106 | ; 2107 | 2108 | enum-base 2109 | : COLON type-with-interr 2110 | { 2111 | $$ = $2; 2112 | } 2113 | ; 2114 | 2115 | enum-body 2116 | : OPEN_BRACE CLOSE_BRACE 2117 | | OPEN_BRACE enum-member-declarations CLOSE_BRACE 2118 | { 2119 | $$ = $2; 2120 | } 2121 | | OPEN_BRACE enum-member-declarations COMMA CLOSE_BRACE 2122 | { 2123 | $$ = $2; 2124 | } 2125 | | enum-body IDENTIFIER_WITH_KEYWORD 2126 | ; 2127 | 2128 | 2129 | enum-member-declarations 2130 | : enum-member-declaration 2131 | { 2132 | $$ = [ $1 ]; 2133 | } 2134 | | enum-member-declarations COMMA enum-member-declaration 2135 | { 2136 | $1.push($3); 2137 | $$ = $1; 2138 | } 2139 | ; 2140 | 2141 | enum-member-declaration 2142 | : IDENTIFIER_WITH_TEMPLATE 2143 | { 2144 | $$ = { 2145 | "name": $1 2146 | }; 2147 | } 2148 | | IDENTIFIER_WITH_TEMPLATE ASSIGN constant-expression 2149 | { 2150 | $$ = { 2151 | "name": $1, 2152 | "value": $3 2153 | }; 2154 | } 2155 | ; 2156 | 2157 | 2158 | struct-bracket 2159 | : local-rank-specifiers ASSIGN variable-initializer 2160 | | local-rank-specifiers 2161 | ; 2162 | 2163 | /* C.2.8 Structs */ 2164 | struct-declaration 2165 | : STRUCT struct-body SEMICOLON 2166 | { 2167 | $$ = { 2168 | "node": "struct", 2169 | "body": $2 2170 | }; 2171 | } 2172 | | STRUCT struct-body 2173 | { 2174 | $$ = { 2175 | "node": "struct", 2176 | "body": $2 2177 | }; 2178 | } 2179 | | STRUCT member-name-with-double-colon OPEN_PARENS CLOSE_PARENS struct-method-body 2180 | { 2181 | $$ = { 2182 | "node": "struct", 2183 | "name": $2 2184 | }; 2185 | } 2186 | | STRUCT member-name-with-double-colon OPEN_PARENS formal-parameter-list CLOSE_PARENS struct-method-body 2187 | { 2188 | $$ = { 2189 | "node": "struct", 2190 | "name": $2, 2191 | "parameter": $4 2192 | }; 2193 | } 2194 | | STRUCT type member-name-with-double-colon OPEN_PARENS CLOSE_PARENS struct-method-body 2195 | { 2196 | $$ = { 2197 | "node": "struct", 2198 | "name": $3 2199 | }; 2200 | } 2201 | | STRUCT type member-name-with-double-colon OPEN_PARENS formal-parameter-list CLOSE_PARENS struct-method-body 2202 | { 2203 | $$ = { 2204 | "node": "struct", 2205 | "name": $3, 2206 | "parameter": $5 2207 | }; 2208 | } 2209 | | STRUCT member-name-with-double-colon SEMICOLON 2210 | { 2211 | $$ = { 2212 | "node": "struct", 2213 | "name": $2 2214 | }; 2215 | } 2216 | | STRUCT type member-name-with-double-colon SEMICOLON 2217 | { 2218 | $$ = { 2219 | "node": "struct", 2220 | "name": $3 2221 | }; 2222 | } 2223 | | STRUCT member-name-with-double-colon struct-body 2224 | { 2225 | $$ = { 2226 | "node": "struct", 2227 | "name": $2, 2228 | "body": $3 2229 | }; 2230 | } 2231 | | STRUCT member-name-with-double-colon struct-body SEMICOLON 2232 | { 2233 | $$ = { 2234 | "node": "struct", 2235 | "name": $2, 2236 | "body": $3 2237 | }; 2238 | } 2239 | | STRUCT member-name-with-double-colon struct-body IDENTIFIER_WITH_TEMPLATE struct-bracket SEMICOLON 2240 | { 2241 | $$ = { 2242 | "node": "struct", 2243 | "name": $2, 2244 | "body": $3 2245 | }; 2246 | } 2247 | | STRUCT member-name-with-double-colon struct-body IDENTIFIER_WITH_TEMPLATE SEMICOLON 2248 | { 2249 | $$ = { 2250 | "node": "struct", 2251 | "name": $2, 2252 | "body": $3 2253 | }; 2254 | } 2255 | | STRUCT member-name-with-double-colon struct-interfaces struct-body 2256 | { 2257 | $$ = { 2258 | "node": "struct", 2259 | "name": $2, 2260 | "base": $3, 2261 | "body": $4 2262 | }; 2263 | } 2264 | | STRUCT member-name-with-double-colon struct-interfaces struct-body SEMICOLON 2265 | { 2266 | $$ = { 2267 | "node": "struct", 2268 | "name": $2, 2269 | "base": $3, 2270 | "body": $4 2271 | }; 2272 | } 2273 | | modifiers STRUCT struct-body 2274 | { 2275 | $$ = { 2276 | "node": "struct", 2277 | "modifiers": $1, 2278 | "body": $4 2279 | }; 2280 | } 2281 | | modifiers STRUCT struct-body IDENTIFIER_WITH_TEMPLATE struct-bracket SEMICOLON 2282 | { 2283 | $$ = { 2284 | "node": "struct", 2285 | "modifiers": $1, 2286 | "body": $3, 2287 | "name": $4 2288 | }; 2289 | } 2290 | | modifiers STRUCT struct-body IDENTIFIER_WITH_TEMPLATE SEMICOLON 2291 | { 2292 | $$ = { 2293 | "node": "struct", 2294 | "modifiers": $1, 2295 | "body": $3, 2296 | "name": $4 2297 | }; 2298 | } 2299 | | modifiers STRUCT member-name-with-double-colon struct-body IDENTIFIER_WITH_TEMPLATE SEMICOLON 2300 | { 2301 | $$ = { 2302 | "node": "struct", 2303 | "modifiers": $1, 2304 | "name": $3, 2305 | "body": $4 2306 | }; 2307 | } 2308 | | modifiers STRUCT member-name-with-double-colon SEIMCOLON 2309 | { 2310 | $$ = { 2311 | "node": "struct", 2312 | "modifiers": $1, 2313 | "name": $3 2314 | }; 2315 | } 2316 | | modifiers STRUCT type member-name-with-double-colon SEMICOLON 2317 | { 2318 | $$ = { 2319 | "node": "struct", 2320 | "modifiers": $1, 2321 | "name": $4 2322 | }; 2323 | } 2324 | | modifiers STRUCT member-name-with-double-colon struct-body 2325 | { 2326 | $$ = { 2327 | "node": "struct", 2328 | "modifiers": $1, 2329 | "name": $3, 2330 | "body": $4 2331 | }; 2332 | } 2333 | | modifiers STRUCT member-name-with-double-colon struct-interfaces struct-body 2334 | { 2335 | $$ = { 2336 | "node": "struct", 2337 | "modifiers": $1, 2338 | "name": $3, 2339 | "base": $4, 2340 | "body": $5 2341 | }; 2342 | } 2343 | | modifiers STRUCT member-name-with-double-colon struct-body SEMICOLON 2344 | { 2345 | $$ = { 2346 | "node": "struct", 2347 | "modifiers": $1, 2348 | "name": $3, 2349 | "body": $4 2350 | }; 2351 | } 2352 | | modifiers STRUCT member-name-with-double-colon struct-interfaces struct-body SEMICOLON 2353 | { 2354 | $$ = { 2355 | "node": "struct", 2356 | "modifiers": $1, 2357 | "name": $3, 2358 | "base": $4, 2359 | "body": $5 2360 | }; 2361 | } 2362 | | modifiers STRUCT struct-body IDENTIFIER_WITH_TEMPLATE SEMICOLON 2363 | { 2364 | $$ = { 2365 | "node": "struct", 2366 | "modifiers": $1, 2367 | "name": $4, 2368 | "body": $3 2369 | }; 2370 | } 2371 | | modifiers CONST STRUCT struct-body 2372 | { 2373 | $$ = { 2374 | "node": "struct", 2375 | "modifiers": $1, 2376 | "body": $4 2377 | }; 2378 | } 2379 | | modifiers CONST STRUCT struct-body identifier-list struct-bracket SEMICOLON 2380 | { 2381 | $$ = { 2382 | "node": "struct", 2383 | "modifiers": $1, 2384 | "name": $5, 2385 | "body": $4 2386 | }; 2387 | } 2388 | | modifiers CONST STRUCT struct-body identifier-list SEMICOLON 2389 | { 2390 | $$ = { 2391 | "node": "struct", 2392 | "modifiers": $1, 2393 | "name": $5, 2394 | "body": $4 2395 | }; 2396 | } 2397 | | modifiers CONST STRUCT member-name-with-double-colon struct-body IDENTIFIER_WITH_TEMPLATE SEMICOLON 2398 | { 2399 | $$ = { 2400 | "node": "struct", 2401 | "modifiers": $1, 2402 | "name": $4, 2403 | "body": $5 2404 | }; 2405 | } 2406 | | modifiers CONST STRUCT member-name-with-double-colon SEIMCOLON 2407 | { 2408 | $$ = { 2409 | "node": "struct", 2410 | "modifiers": $1, 2411 | "name": $4 2412 | }; 2413 | } 2414 | | modifiers CONST STRUCT type member-name-with-double-colon SEMICOLON 2415 | { 2416 | $$ = { 2417 | "node": "struct", 2418 | "modifiers": $1, 2419 | "name": $5 2420 | }; 2421 | } 2422 | | modifiers CONST STRUCT member-name-with-double-colon struct-body 2423 | { 2424 | $$ = { 2425 | "node": "struct", 2426 | "modifiers": $1, 2427 | "name": $4, 2428 | "body": $5 2429 | }; 2430 | } 2431 | | modifiers CONST STRUCT member-name-with-double-colon struct-interfaces struct-body 2432 | { 2433 | $$ = { 2434 | "node": "struct", 2435 | "modifiers": $1, 2436 | "name": $4, 2437 | "base": $5, 2438 | "body": $6 2439 | }; 2440 | } 2441 | | modifiers CONST STRUCT member-name-with-double-colon struct-body SEMICOLON 2442 | { 2443 | $$ = { 2444 | "node": "struct", 2445 | "modifiers": $1, 2446 | "name": $4, 2447 | "body": $5 2448 | }; 2449 | } 2450 | | modifiers CONST STRUCT member-name-with-double-colon struct-interfaces struct-body SEMICOLON 2451 | { 2452 | $$ = { 2453 | "node": "struct", 2454 | "modifiers": $1, 2455 | "name": $4, 2456 | "base": $5, 2457 | "body": $6 2458 | }; 2459 | } 2460 | | modifiers CONST STRUCT struct-body IDENTIFIER_WITH_TEMPLATE SEMICOLON 2461 | { 2462 | $$ = { 2463 | "node": "struct", 2464 | "modifiers": $1, 2465 | "name": $5, 2466 | "body": $4 2467 | }; 2468 | } 2469 | | CONST struct-declaration 2470 | { 2471 | $$ = $2; 2472 | } 2473 | | STRUCT struct-body IDENTIFIER_WITH_TEMPLATE SEMICOLON 2474 | { 2475 | $$ = { 2476 | "node": "struct", 2477 | "name": $3, 2478 | "body": $2 2479 | }; 2480 | } 2481 | ; 2482 | 2483 | struct-method-body 2484 | : CONST block 2485 | | block 2486 | ; 2487 | 2488 | struct-interfaces 2489 | : COLON base-list 2490 | { 2491 | $$ = $2; 2492 | } 2493 | ; 2494 | 2495 | struct-body 2496 | : OPEN_BRACE struct-member-list CLOSE_BRACE 2497 | { 2498 | $$ = $2; 2499 | } 2500 | | OPEN_BRACE CLOSE_BRACE 2501 | ; 2502 | 2503 | struct-member-list 2504 | : struct-member-list struct-with-access-specifier 2505 | { 2506 | 2507 | prev_modifier = $1[$1.length-1]["modifiers"]; 2508 | 2509 | if($2["modifiers"]){ 2510 | $1.push($2); 2511 | } 2512 | else{ 2513 | 2514 | if(prev_modifier){ 2515 | $2["modifiers"] = prev_modifier; 2516 | } 2517 | else{ 2518 | $1[$1.length-1]["modifiers"] = [ "public" ]; 2519 | $2["modifiers"] = [ "public" ]; 2520 | } 2521 | $1.push($2); 2522 | } 2523 | 2524 | $$ = $1; 2525 | } 2526 | | struct-with-access-specifier 2527 | { 2528 | $$ = [ $1 ]; 2529 | } 2530 | ; 2531 | 2532 | 2533 | 2534 | struct-with-access-specifier 2535 | : access-specifier COLON struct-member-declaration 2536 | { 2537 | 2538 | $3["modifiers"] = [ $1 ]; 2539 | 2540 | $$ = $3; 2541 | 2542 | } 2543 | | access-specifier COLON 2544 | { 2545 | $$ = { 2546 | "modifiers": [ $1 ], 2547 | "node": "null" 2548 | }; 2549 | } 2550 | | struct-member-declaration 2551 | { 2552 | $$ = $1; 2553 | } 2554 | ; 2555 | 2556 | struct-member-declarations 2557 | : struct-member-declaration 2558 | { 2559 | $$ = [ $1 ]; 2560 | } 2561 | | struct-member-declarations struct-member-declaration 2562 | { 2563 | if($2!=';'){ 2564 | $1.push($2); 2565 | $$ = $1; 2566 | } 2567 | 2568 | } 2569 | ; 2570 | 2571 | struct-member-declaration 2572 | : field-declaration 2573 | { 2574 | $$ = $1; 2575 | } 2576 | | class-method-declaration 2577 | { 2578 | $$ = $1; 2579 | } 2580 | | property-declaration 2581 | { 2582 | $$ = $1; 2583 | } 2584 | | operator-declaration 2585 | { 2586 | $$ = $1; 2587 | } 2588 | | struct-declaration 2589 | { 2590 | $$ = $1; 2591 | } 2592 | | enum-declaration 2593 | { 2594 | $$ = $1; 2595 | } 2596 | | static-constructor-declaration 2597 | { 2598 | $$ = $1; 2599 | } 2600 | | SEMICOLON 2601 | { 2602 | $$ = $1; 2603 | } 2604 | ; 2605 | 2606 | 2607 | 2608 | /* C.2.6 compilationUnit */ 2609 | compilationUnit 2610 | : EOF 2611 | | block_or_statement_list EOF 2612 | { 2613 | return { 2614 | "node": "CompilationUnit", 2615 | "member": $1 2616 | }; 2617 | } 2618 | ; 2619 | 2620 | block_or_statement_list 2621 | : block_or_statement_list block_or_statement 2622 | { 2623 | $1.push($2); 2624 | $$ = $1; 2625 | } 2626 | | block_or_statement 2627 | { 2628 | $$ = [ $1 ]; 2629 | } 2630 | ; 2631 | 2632 | block_or_statement 2633 | : class-declaration 2634 | { 2635 | $$ = $1; 2636 | } 2637 | | method-declaration 2638 | { 2639 | $$ = { 2640 | "node": "null" 2641 | }; 2642 | } 2643 | | class-member-declaration 2644 | { 2645 | $$ = { 2646 | "node": "null" 2647 | }; 2648 | } 2649 | | namespace-declaration 2650 | { 2651 | $$ = $1; 2652 | } 2653 | | struct-declaration 2654 | { 2655 | $$ = $1; 2656 | } 2657 | | enum-declaration 2658 | { 2659 | $$ = $1; 2660 | } 2661 | | extern-declaration 2662 | { 2663 | $$ = { 2664 | "node": "null" 2665 | }; 2666 | } 2667 | | SEMICOLON 2668 | { 2669 | $$ = { 2670 | "node": "null" 2671 | }; 2672 | } 2673 | ; 2674 | 2675 | extern-declaration 2676 | : EXTERN STRING_LITERAL OPEN_BRACE block_or_statement_list CLOSE_BRACE 2677 | | EXTERN STRING_LITERAL OPEN_BRACE CLOSE_BRACE 2678 | | EXTERN STRUCT class-method-declaration 2679 | | EXTERN class-method-declaration 2680 | ; 2681 | 2682 | namespace-declaration 2683 | : NAMESPACE namespace-or-type-name OPEN_BRACE block_or_statement_list CLOSE_BRACE 2684 | { 2685 | $$ = { 2686 | "node": "namespace", 2687 | "name": $2, 2688 | "body": $4 2689 | }; 2690 | } 2691 | | NAMESPACE namespace-or-type-name OPEN_BRACE CLOSE_BRACE 2692 | { 2693 | $$ = { 2694 | "node": "namespace", 2695 | "name": $2 2696 | }; 2697 | } 2698 | | NAMESPACE INTERNAL OPEN_BRACE block_or_statement_list CLOSE_BRACE 2699 | { 2700 | $$ = { 2701 | "node": "namespace", 2702 | "name": $2, 2703 | "body": $4 2704 | }; 2705 | } 2706 | | NAMESPACE INTERNAL OPEN_BRACE CLOSE_BRACE 2707 | { 2708 | $$ = { 2709 | "node": "namespace", 2710 | "name": $2 2711 | }; 2712 | } 2713 | | NAMESPACE OPEN_BRACE block_or_statement_list CLOSE_BRACE 2714 | { 2715 | $$ = { 2716 | "node": "namespace", 2717 | "body": $3 2718 | }; 2719 | } 2720 | | NAMESPACE OPEN_BRACE CLOSE_BRACE 2721 | { 2722 | $$ = { 2723 | "node": "namespace" 2724 | }; 2725 | } 2726 | | namespace-declaration SEMICOLON 2727 | { 2728 | $$ = $1; 2729 | } 2730 | ; 2731 | 2732 | 2733 | 2734 | using-directives 2735 | : using-directive 2736 | { 2737 | $$ = [ $1 ]; 2738 | } 2739 | | using-directives using-directive 2740 | { 2741 | $1.push($2); 2742 | $$ = $1; 2743 | } 2744 | ; 2745 | 2746 | using-directive 2747 | : using-alias-directive 2748 | { 2749 | $$ = $1; 2750 | } 2751 | | using-namespace-directive 2752 | { 2753 | $$ = $1; 2754 | } 2755 | ; 2756 | 2757 | using-alias-directive 2758 | : USING NAMESPACE IDENTIFIER_WITH_TEMPLATE ASSIGN namespace-or-type-name SEMICOLON 2759 | { 2760 | $$ = { 2761 | "node" : "using", 2762 | "name" : $3 2763 | }; 2764 | } 2765 | | USING IDENTIFIER_WITH_TEMPLATE ASSIGN namespace-or-type-name SEMICOLON 2766 | { 2767 | $$ = { 2768 | "node" : "using", 2769 | "name" : $2 2770 | }; 2771 | } 2772 | ; 2773 | 2774 | using-namespace-directive 2775 | : USING NAMESPACE namespace-name SEMICOLON 2776 | { 2777 | $$ = { 2778 | "node" : "using", 2779 | "name" : $3 2780 | }; 2781 | } 2782 | | USING namespace-name SEMICOLON 2783 | { 2784 | $$ = { 2785 | "node" : "using", 2786 | "name" : $2 2787 | }; 2788 | } 2789 | ; 2790 | 2791 | 2792 | 2793 | 2794 | /* Modifier */ 2795 | 2796 | 2797 | modifier 2798 | : UNSAFE 2799 | | PUBLIC 2800 | | PARTIAL 2801 | | PROTECTED 2802 | | INTERNAL 2803 | | PRIVATE 2804 | | ABSTRACT 2805 | | STATIC 2806 | | READONLY 2807 | | VOLATILE 2808 | | VIRTUAL 2809 | | OVERRIDE 2810 | | IDENTIFIER STATIC 2811 | { 2812 | $$ = $1 + " " + $2; 2813 | } 2814 | | TYPEDEF 2815 | | EXPLICIT 2816 | | IMPLICIT 2817 | ; 2818 | 2819 | modifiers 2820 | : modifier 2821 | { 2822 | $$ = [ $1 ]; 2823 | } 2824 | | modifiers modifier 2825 | { 2826 | $1.push($2); 2827 | $$ = $1; 2828 | } 2829 | ; 2830 | 2831 | /* C.2.7 Classes */ 2832 | 2833 | class-key 2834 | : FRIEND CLASS 2835 | | PUBLIC REF CLASS 2836 | | REF CLASS 2837 | | CLASS 2838 | | TYPEDEF UNION 2839 | | UNION 2840 | ; 2841 | 2842 | class-declaration 2843 | : class-key class-body identifier-list SEMICOLON 2844 | { 2845 | $$ = { 2846 | "node": "class", 2847 | "body": $2 2848 | }; 2849 | } 2850 | | class-key class-body SEMICOLON 2851 | { 2852 | $$ = { 2853 | "node": "class", 2854 | "body": $2 2855 | }; 2856 | } 2857 | | class-key identifier-list class-suffix identifier-list SEMICOLON 2858 | { 2859 | $$ = { 2860 | "node": "class", 2861 | "name": $2["name"] 2862 | }; 2863 | 2864 | if($2["typeParameters"]){ 2865 | $$["typeParameters"] = $2["typeParameters"]; 2866 | } 2867 | 2868 | if($3=="abstract"){ 2869 | $$["modifiers"] = [ $3 ]; 2870 | } 2871 | } 2872 | | class-key identifier-list class-suffix SEMICOLON 2873 | { 2874 | $$ = { 2875 | "node": "class", 2876 | "name": $2["name"] 2877 | }; 2878 | 2879 | if($2["typeParameters"]){ 2880 | $$["typeParameters"] = $2["typeParameters"]; 2881 | } 2882 | 2883 | if($3=="abstract"){ 2884 | $$["modifiers"] = [ $3 ]; 2885 | } 2886 | } 2887 | | class-key identifier-list class-suffix class-body 2888 | { 2889 | $$ = { 2890 | "node": "class", 2891 | "name": $2["name"], 2892 | "body": $4 2893 | }; 2894 | 2895 | if($2["typeParameters"]){ 2896 | $$["typeParameters"] = $2["typeParameters"]; 2897 | } 2898 | 2899 | if($3=="abstract"){ 2900 | $$["modifiers"] = [ $3 ]; 2901 | } 2902 | } 2903 | | class-key identifier-list class-suffix class-base class-body 2904 | { 2905 | $$ = { 2906 | "node": "class", 2907 | "name": $2["name"], 2908 | "base": $4, 2909 | "body": $5 2910 | }; 2911 | 2912 | if($2["typeParameters"]){ 2913 | $$["typeParameters"] = $2["typeParameters"]; 2914 | } 2915 | 2916 | if($3=="abstract"){ 2917 | $$["modifiers"] = [ $3 ]; 2918 | } 2919 | } 2920 | | class-key identifier-list class-suffix class-body identifier-list SEMICOLON 2921 | { 2922 | $$ = { 2923 | "node": "class", 2924 | "name": $2["name"], 2925 | "body": $4 2926 | }; 2927 | 2928 | if($2["typeParameters"]){ 2929 | $$["typeParameters"] = $2["typeParameters"]; 2930 | } 2931 | 2932 | if($3=="abstract"){ 2933 | $$["modifiers"] = [ $3 ]; 2934 | } 2935 | } 2936 | | class-key identifier-list class-suffix class-body SEMICOLON 2937 | { 2938 | $$ = { 2939 | "node": "class", 2940 | "name": $2["name"], 2941 | "body": $4 2942 | }; 2943 | 2944 | if($2["typeParameters"]){ 2945 | $$["typeParameters"] = $2["typeParameters"]; 2946 | } 2947 | 2948 | if($3=="abstract"){ 2949 | $$["modifiers"] = [ $3 ]; 2950 | } 2951 | } 2952 | | class-key identifier-list class-suffix class-base class-body identifier-list SEMICOLON 2953 | { 2954 | $$ = { 2955 | "node": "class", 2956 | "name": $2["name"], 2957 | "base": $4, 2958 | "body": $5 2959 | }; 2960 | 2961 | if($2["typeParameters"]){ 2962 | $$["typeParameters"] = $2["typeParameters"]; 2963 | } 2964 | 2965 | if($3=="abstract"){ 2966 | $$["modifiers"] = [ $3 ]; 2967 | } 2968 | } 2969 | | class-key identifier-list class-suffix class-base class-body SEMICOLON 2970 | { 2971 | $$ = { 2972 | "node": "class", 2973 | "name": $2["name"], 2974 | "base": $4, 2975 | "body": $5 2976 | }; 2977 | 2978 | if($2["typeParameters"]){ 2979 | $$["typeParameters"] = $2["typeParameters"]; 2980 | } 2981 | 2982 | if($3=="abstract"){ 2983 | $$["modifiers"] = [ $3 ]; 2984 | } 2985 | } 2986 | ; 2987 | 2988 | 2989 | 2990 | identifier-list 2991 | : identifier-list DOUBLE_COLON IDENTIFIER_WITH_TEMPLATE 2992 | { 2993 | if($3["typeParameters"]){ 2994 | $$["name"] = $3["name"]; 2995 | $$["typeParameters"] = $3["typeParameters"]; 2996 | } 2997 | else { 2998 | $$["name"] = $3; 2999 | } 3000 | } 3001 | | identifier-list IDENTIFIER_WITH_TEMPLATE 3002 | { 3003 | if($2["typeParameters"]){ 3004 | $$["name"] = $2["name"]; 3005 | $$["typeParameters"] = $2["typeParameters"]; 3006 | } 3007 | else { 3008 | $$["name"] = $2; 3009 | } 3010 | } 3011 | | IDENTIFIER_WITH_TEMPLATE 3012 | { 3013 | if($1["typeParameters"]){ 3014 | $$["name"] = $1["name"]; 3015 | $$["typeParameters"] = $1["typeParameters"]; 3016 | } 3017 | else { 3018 | $$["name"] = $1; 3019 | } 3020 | } 3021 | ; 3022 | 3023 | class-suffix 3024 | : ABSTRACT 3025 | | %empty 3026 | ; 3027 | 3028 | class-base 3029 | : COLON base-list 3030 | { 3031 | $$ = $2; 3032 | } 3033 | ; 3034 | 3035 | base-list 3036 | : base-list COMMA base-specifier 3037 | { 3038 | $1.push($3); 3039 | $$ = $1; 3040 | } 3041 | | base-specifier 3042 | { 3043 | $$ = [ $1 ]; 3044 | } 3045 | ; 3046 | 3047 | base-specifier 3048 | : type-with-interr 3049 | { 3050 | $$ = $1; 3051 | } 3052 | | VIRTUAL access-specifier type-with-interr 3053 | { 3054 | $$ = $3; 3055 | } 3056 | | VIRTUAL type-with-interr 3057 | { 3058 | $$ = $2; 3059 | } 3060 | | access-specifier VIRTUAL type-with-interr 3061 | { 3062 | $$ = $3; 3063 | } 3064 | | access-specifier type-with-interr 3065 | { 3066 | $$ = $2; 3067 | } 3068 | ; 3069 | 3070 | access-specifier 3071 | : PRIVATE 3072 | | PROTECTED 3073 | | PUBLIC 3074 | | INTERNAL 3075 | | PROTECTED PRIVATE 3076 | { 3077 | $$ = $1 + " " + $2; 3078 | } 3079 | | type 3080 | ; 3081 | 3082 | 3083 | class-body 3084 | : OPEN_BRACE CLOSE_BRACE 3085 | | OPEN_BRACE member-list CLOSE_BRACE 3086 | { 3087 | $$ = $2; 3088 | } 3089 | ; 3090 | 3091 | 3092 | 3093 | 3094 | member-list 3095 | : member-list class-with-access-specifier 3096 | { 3097 | prev_modifier = $1[$1.length-1]["modifiers"]; 3098 | 3099 | if($2["modifiers"]){ 3100 | $1.push($2); 3101 | } 3102 | else{ 3103 | 3104 | if(prev_modifier){ 3105 | $2["modifiers"] = prev_modifier; 3106 | } 3107 | else{ 3108 | $1[$1.length-1]["modifiers"] = [ "public" ]; 3109 | $2["modifiers"] = [ "public" ]; 3110 | } 3111 | $1.push($2); 3112 | } 3113 | 3114 | $$ = $1; 3115 | } 3116 | | class-with-access-specifier 3117 | { 3118 | $$ = [ $1 ]; 3119 | } 3120 | ; 3121 | 3122 | class-with-access-specifier 3123 | : access-specifier access-specifier COLON class-member-declaration 3124 | { 3125 | $4["modifiers"] = [ $1 ]; 3126 | $4["modifiers"].push($2); 3127 | 3128 | $$ = $4; 3129 | } 3130 | | access-specifier COLON class-member-declaration 3131 | { 3132 | $3["modifiers"]= [ $1 ]; 3133 | $$ = $3; 3134 | } 3135 | | access-specifier COLON 3136 | { 3137 | $$ = { 3138 | "modifiers": [ $1 ], 3139 | "node": "null" 3140 | }; 3141 | } 3142 | | class-member-declaration 3143 | { 3144 | $$ = $1; 3145 | } 3146 | ; 3147 | 3148 | class-member-declarations 3149 | : class-member-declaration 3150 | { 3151 | $$ = [ $1 ]; 3152 | } 3153 | | class-member-declarations class-member-declaration 3154 | { 3155 | $1.push($2); 3156 | $$ = $1; 3157 | } 3158 | ; 3159 | 3160 | class-member-declaration 3161 | : operator-declaration 3162 | { 3163 | $$ = $1; 3164 | } 3165 | | class-method-declaration 3166 | { 3167 | $$ = $1; 3168 | } 3169 | | field-declaration 3170 | { 3171 | $$ = $1; 3172 | } 3173 | | property-declaration 3174 | { 3175 | $$ = $1; 3176 | } 3177 | | destructor-declaration 3178 | { 3179 | $$ = $1; 3180 | } 3181 | | using-directive 3182 | { 3183 | $$ = $1; 3184 | } 3185 | | constant-declaration 3186 | { 3187 | $$ = $1; 3188 | } 3189 | | FRIEND CLASS IDENTIFIER_WITH_TEMPLATE SEMICOLON 3190 | { 3191 | $$ = { 3192 | "node": "class" 3193 | }; 3194 | if($1["typeParameters"]){ 3195 | $$["name"] = $3["name"]; 3196 | $$["typeParameters"] = $3["typeParameters"]; 3197 | } 3198 | else { 3199 | $$["name"] = $3; 3200 | } 3201 | } 3202 | | class-declaration 3203 | { 3204 | $$ = $1; 3205 | } 3206 | | struct-declaration 3207 | { 3208 | $$ = $1; 3209 | } 3210 | | enum-declaration 3211 | { 3212 | $$ = $1; 3213 | } 3214 | | static-constructor-declaration 3215 | { 3216 | $$ = $1; 3217 | } 3218 | | SEMICOLON 3219 | { 3220 | $$ = { 3221 | "node": "null" 3222 | }; 3223 | } 3224 | ; 3225 | 3226 | 3227 | constant-declaration 3228 | : type-with-interr constant-declarators SEMICOLON 3229 | { 3230 | $$ = { 3231 | "node" : "constant", 3232 | "type" : $1, 3233 | "name" : $2 3234 | }; 3235 | } 3236 | | modifiers type-with-interr constant-declarators SEMICOLON 3237 | { 3238 | $$ = { 3239 | "node": "constant", 3240 | "modifiers": $1, 3241 | "type": $2, 3242 | "name": $3 3243 | }; 3244 | } 3245 | ; 3246 | 3247 | constant-declarators 3248 | : constant-declarator 3249 | { 3250 | $$ = [ $1 ]; 3251 | } 3252 | | constant-declarators COMMA STAR constant-declarator 3253 | { 3254 | $1.push($4); 3255 | $$ = $1; 3256 | } 3257 | | constant-declarators COMMA constant-declarator 3258 | { 3259 | $1.push($3); 3260 | $$ = $1; 3261 | } 3262 | ; 3263 | 3264 | constant-declarator 3265 | : IDENTIFIER_WITH_TEMPLATE ASSIGN constant-expression 3266 | { 3267 | $$ = { 3268 | "node":"variable", 3269 | "value": $3 3270 | }; 3271 | if($1["typeParameters"]){ 3272 | $$["name"] = $1["name"]; 3273 | $$["typeParameters"] = $1["typeParameters"]; 3274 | } 3275 | else { 3276 | $$["name"] = $1; 3277 | } 3278 | } 3279 | | IDENTIFIER_WITH_TEMPLATE 3280 | { 3281 | $$ = { 3282 | "node":"variable" 3283 | }; 3284 | if($1["typeParameters"]){ 3285 | $$["name"] = $1["name"]; 3286 | $$["typeParameters"] = $1["typeParameters"]; 3287 | } 3288 | else { 3289 | $$["name"] = $1; 3290 | } 3291 | } 3292 | ; 3293 | 3294 | field-declaration 3295 | : field-variable-declarators SEMICOLON 3296 | { 3297 | $$ = { 3298 | "node": "field", 3299 | "name": $1 3300 | }; 3301 | } 3302 | | modifiers field-variable-declarators SEMICOLON 3303 | { 3304 | $$ = { 3305 | "node": "field", 3306 | "modifiers": $1, 3307 | "name": $2 3308 | }; 3309 | } 3310 | | field-variable-declarators function-pointer SEMICOLON 3311 | { 3312 | $$ = { 3313 | "node": "field", 3314 | "name": $1 3315 | }; 3316 | } 3317 | | modifiers field-variable-declarators function-pointer SEMICOLON 3318 | { 3319 | $$ = { 3320 | "node": "field", 3321 | "modifiers": $1, 3322 | "name": $2 3323 | }; 3324 | } 3325 | | field-variable-declarators function-pointer static-constructor-parameter 3326 | { 3327 | $$ = { 3328 | "node": "field", 3329 | "name": $1 3330 | }; 3331 | } 3332 | | modifiers field-variable-declarators function-pointer static-constructor-parameter 3333 | { 3334 | $$ = { 3335 | "node": "field", 3336 | "modifiers": $1, 3337 | "name": $2 3338 | }; 3339 | } 3340 | ; 3341 | 3342 | function-pointer 3343 | : OPEN_PARENS STAR member-name-with-double-colon-star CLOSE_PARENS 3344 | { 3345 | $$ = $1 + $2 + $3 + $4; 3346 | } 3347 | | OPEN_PARENS member-name-with-double-colon-star CLOSE_PARENS 3348 | { 3349 | $$ = $1 + $2 + $3; 3350 | } 3351 | | OPEN_PARENS CLOSE_PARENS 3352 | { 3353 | $$ = $1 + $2; 3354 | } 3355 | ; 3356 | 3357 | field-variable-declarators 3358 | : field-variable-declarators COMMA STAR field-variable-declarator 3359 | { 3360 | $1.push($4); 3361 | $$ = $1; 3362 | } 3363 | | field-variable-declarators COMMA field-variable-declarator 3364 | { 3365 | $1.push($3); 3366 | $$ = $1; 3367 | } 3368 | | field-variable-declarator 3369 | { 3370 | $$ = [ $1 ]; 3371 | } 3372 | ; 3373 | 3374 | field-variable-declarator 3375 | : member-name-with-double-colon ASSIGN variable-initializer 3376 | { 3377 | $$ = { 3378 | "node":"variable", 3379 | "name": $1, 3380 | "initialize": $3 3381 | }; 3382 | } 3383 | | member-name-with-double-colon 3384 | { 3385 | $$ = { 3386 | "node":"variable", 3387 | "name": $1 3388 | }; 3389 | } 3390 | ; 3391 | 3392 | 3393 | variable-declarators 3394 | : variable-declarators COMMA STAR variable-declarator 3395 | { 3396 | $1.push($4); 3397 | $$ = $1; 3398 | } 3399 | | variable-declarators COMMA variable-declarator 3400 | { 3401 | $1.push($3); 3402 | $$ = $1; 3403 | } 3404 | | variable-declarator 3405 | { 3406 | $$ = [ $1 ]; 3407 | } 3408 | ; 3409 | 3410 | variable-declarator 3411 | : type ASSIGN variable-initializer 3412 | { 3413 | $$ = { 3414 | "node": "variable", 3415 | "name": $1, 3416 | "initialize": $3 3417 | }; 3418 | } 3419 | | type 3420 | { 3421 | $$ = { 3422 | "node": "variable", 3423 | "name": $1 3424 | }; 3425 | } 3426 | ; 3427 | 3428 | variable-initializer 3429 | : expression 3430 | { 3431 | $$ =$1; 3432 | } 3433 | | array-initializer 3434 | { 3435 | $$ = $1; 3436 | } 3437 | ; 3438 | 3439 | 3440 | method-declaration 3441 | : method-header method-prefixs ctor-initializer block 3442 | | method-header ctor-initializer block 3443 | | method-header method-prefixs block 3444 | | method-header block 3445 | ; 3446 | 3447 | ctor-initializer 3448 | : COLON mem-initializer-list 3449 | ; 3450 | 3451 | mem-initializer-list 3452 | : mem-initializer COMMA mem-initializer-list 3453 | | mem-initializer 3454 | ; 3455 | 3456 | mem-initializer 3457 | : type OPEN_PARENS member-name-with-double-colon-list CLOSE_PARENS 3458 | | type OPEN_PARENS argument-list CLOSE_PARENS 3459 | | type OPEN_PARENS CLOSE_PARENS 3460 | ; 3461 | 3462 | member-name-with-double-colon-list 3463 | : member-name-with-double-colon-list COMMA member-name-with-double-colon 3464 | | member-name-with-double-colon-literal 3465 | ; 3466 | 3467 | member-name-with-double-colon-literal 3468 | : STRUCT expression 3469 | |` expression 3470 | | member-name-with-double-colon-literal local-rank-specifiers 3471 | ; 3472 | 3473 | class-method-declaration 3474 | : class-method-header method-prefixs block SEMICOLON 3475 | { 3476 | $$ = $1; 3477 | } 3478 | | class-method-header method-prefixs ctor-initializer block SEMICOLON 3479 | { 3480 | $$ = $1; 3481 | } 3482 | | class-method-header method-prefixs ctor-initializer block 3483 | { 3484 | $$ = $1; 3485 | } 3486 | | class-method-header method-prefixs block 3487 | { 3488 | $$ = $1; 3489 | } 3490 | | class-method-header method-prefixs SEMICOLON 3491 | { 3492 | $$ = $1; 3493 | } 3494 | | class-method-header method-prefixs 3495 | { 3496 | $$ = $1; 3497 | } 3498 | | class-method-header IDENTIFIER_WITH_KEYWORD block SEMICOLON 3499 | { 3500 | $$ = $1; 3501 | } 3502 | | class-method-header block SEMICOLON 3503 | { 3504 | $$ = $1; 3505 | } 3506 | | class-method-header ctor-initializer block SEMICOLON 3507 | { 3508 | $$ = $1; 3509 | } 3510 | | class-method-header ctor-initializer block 3511 | { 3512 | $$ = $1; 3513 | } 3514 | | class-method-header IDENTIFIER_WITH_KEYWORD block 3515 | { 3516 | $$ = $1; 3517 | } 3518 | | class-method-header block 3519 | { 3520 | $$ = $1; 3521 | } 3522 | | class-method-header IDENTIFIER_WITH_KEYWORD OPEN_PARENS argument-list CLOSE_PARENS SEMICOLON 3523 | { 3524 | $$ = $1; 3525 | } 3526 | | class-method-header IDENTIFIER_WITH_KEYWORD SEMICOLON 3527 | { 3528 | $$ = $1; 3529 | } 3530 | | class-method-header SEMICOLON 3531 | { 3532 | $$ = $1; 3533 | } 3534 | | class-method-header 3535 | { 3536 | $$ = $1; 3537 | } 3538 | ; 3539 | 3540 | method-prefixs 3541 | : method-prefixs method-prefix 3542 | | method-prefix 3543 | ; 3544 | 3545 | method-prefix 3546 | : CONST type 3547 | | CONST OVERRIDE 3548 | | CONST 3549 | | OVERRIDE 3550 | ; 3551 | 3552 | 3553 | class-method-header 3554 | : member-name-with-double-colon OPEN_PARENS formal-parameter-list CLOSE_PARENS class-method-header 3555 | { 3556 | $$ = { 3557 | "node": "constructor", 3558 | "name": $1, 3559 | "parameter": $3 3560 | }; 3561 | } 3562 | | member-name-with-double-colon OPEN_PARENS CLOSE_PARENS class-method-header 3563 | { 3564 | $$ = { 3565 | "node": "constructor", 3566 | "name": $1 3567 | }; 3568 | } 3569 | | member-name-with-double-colon OPEN_PARENS formal-parameter-list CLOSE_PARENS 3570 | { 3571 | $$ = { 3572 | "node": "constructor", 3573 | "name": $1, 3574 | "parameter": $3 3575 | }; 3576 | } 3577 | | member-name-with-double-colon OPEN_PARENS CLOSE_PARENS 3578 | { 3579 | $$ = { 3580 | "node": "constructor", 3581 | "name": $1 3582 | }; 3583 | } 3584 | | type member-name-with-double-colon OPEN_PARENS formal-parameter-list CLOSE_PARENS 3585 | { 3586 | $$ = { 3587 | "node": "method", 3588 | "type": $1, 3589 | "name": $2, 3590 | "parameter": $4 3591 | }; 3592 | } 3593 | | type member-name-with-double-colon OPEN_PARENS CLOSE_PARENS 3594 | { 3595 | $$ = { 3596 | "node": "method", 3597 | "type": $1, 3598 | "name": $2 3599 | }; 3600 | } 3601 | | type OPEN_PARENS formal-parameter-list CLOSE_PARENS class-method-header 3602 | { 3603 | $$ = { 3604 | "node": "constructor", 3605 | "name": $1 3606 | }; 3607 | } 3608 | | type OPEN_PARENS CLOSE_PARENS class-method-header 3609 | { 3610 | $$ = { 3611 | "node": "constructor", 3612 | "name": $1 3613 | }; 3614 | } 3615 | | type OPEN_PARENS formal-parameter-list CLOSE_PARENS 3616 | { 3617 | $$ = { 3618 | "node": "constructor", 3619 | "name": $1 , 3620 | "parameter": $3 3621 | }; 3622 | } 3623 | | type OPEN_PARENS CLOSE_PARENS 3624 | { 3625 | $$ = { 3626 | "node": "constructor", 3627 | "name": $1 3628 | }; 3629 | } 3630 | | modifiers type function-pointer OPEN_PARENS formal-parameter-list CLOSE_PARENS 3631 | { 3632 | $$ = { 3633 | "node": "method", 3634 | "modifiers": $1, 3635 | "type": $2, 3636 | "name": $3, 3637 | "parameter": $5 3638 | }; 3639 | } 3640 | | modifiers type function-pointer OPEN_PARENS CLOSE_PARENS 3641 | { 3642 | $$ = { 3643 | "node": "method", 3644 | "modifiers": $1, 3645 | "type": $2, 3646 | "name": $3 3647 | }; 3648 | } 3649 | | modifiers type member-name-with-double-colon OPEN_PARENS formal-parameter-list CLOSE_PARENS 3650 | { 3651 | $$ = { 3652 | "node": "method", 3653 | "modifiers": $1, 3654 | "type": $2, 3655 | "name": $3, 3656 | "parameter": $5 3657 | }; 3658 | } 3659 | | modifiers type member-name-with-double-colon OPEN_PARENS CLOSE_PARENS 3660 | { 3661 | $$ = { 3662 | "node": "method", 3663 | "modifiers": $1, 3664 | "type": $2, 3665 | "name": $3 3666 | }; 3667 | } 3668 | | modifiers member-name-with-double-colon OPEN_PARENS formal-parameter-list CLOSE_PARENS 3669 | { 3670 | $$ = { 3671 | "node": "constructor", 3672 | "modifiers": $1, 3673 | "name": $2, 3674 | "parameter": $4 3675 | }; 3676 | } 3677 | | modifiers member-name-with-double-colon OPEN_PARENS CLOSE_PARENS 3678 | { 3679 | $$ = { 3680 | "node": "constructor", 3681 | "modifiers": $1, 3682 | "name": $2 3683 | }; 3684 | } 3685 | | member-name-with-double-colon 3686 | { 3687 | $$ = { 3688 | "node": "null" 3689 | }; 3690 | } 3691 | | class-method-header ASSIGN variable-initializer 3692 | { 3693 | $$ = $1; 3694 | } 3695 | | class-method-header CONST ASSIGN variable-initializer 3696 | { 3697 | $$ = $1; 3698 | } 3699 | ; 3700 | 3701 | method-header 3702 | : method-types member-name-with-double-colon OPEN_PARENS formal-parameter-list CLOSE_PARENS 3703 | | method-types member-name-with-double-colon OPEN_PARENS CLOSE_PARENS 3704 | | member-name-with-double-colon OPEN_PARENS formal-parameter-list CLOSE_PARENS 3705 | | member-name-with-double-colon OPEN_PARENS CLOSE_PARENS 3706 | ; 3707 | 3708 | 3709 | method-types 3710 | : method-types method-type 3711 | { 3712 | $$ = $1 + " " + $2; 3713 | } 3714 | | method-type 3715 | { 3716 | $$ = $1; 3717 | } 3718 | ; 3719 | 3720 | method-type 3721 | : type 3722 | { 3723 | $$ = $1 ; 3724 | } 3725 | ; 3726 | 3727 | member-name-with-double-colon-star 3728 | : type STAR member-name-with-double-colon-star 3729 | { 3730 | $$ = $1 + "" + $2 + "" + $3 ; 3731 | } 3732 | | type member-name-with-double-colon-star 3733 | { 3734 | $$ = $1 + "" + $2 ; 3735 | } 3736 | | member-name-with-double-colon-star member-name DOUBLE_COLON STAR member-name 3737 | { 3738 | $$ = $1 + "" + $2 + "" + $3 + "" + $4 + "" + $5; 3739 | } 3740 | | member-name-with-double-colon-star member-name DOUBLE_COLON TILDE member-name 3741 | { 3742 | $$ = $1 + "" + $2 + "" + $3 + "" + $4 + "" + $5; 3743 | } 3744 | | member-name-with-double-colon-star member-name DOUBLE_COLON member-name 3745 | { 3746 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 3747 | } 3748 | | member-name-with-double-colon-star COMMA STAR member-name 3749 | { 3750 | $$ = $1 + "" + $2 + "" + $3 + "" + $4; 3751 | } 3752 | | member-name-with-double-colon-star COMMA member-name 3753 | { 3754 | $$ = $1 + "" + $2 + "" + $3; 3755 | } 3756 | | member-name-with-double-colon-star STAR member-name 3757 | { 3758 | $$ = $1 + "" + $2 + "" + $3; 3759 | } 3760 | | member-name-with-double-colon-star member-name 3761 | { 3762 | $$ = $1 + "" + $2; 3763 | } 3764 | | type STAR 3765 | { 3766 | $$ = $1 + "" + $2; 3767 | } 3768 | | type 3769 | { 3770 | $$ = $1; 3771 | } 3772 | ; 3773 | 3774 | member-name-with-double-colon 3775 | : type member-name-with-double-colon 3776 | { 3777 | $$ = $1 + " " +$2; 3778 | } 3779 | | member-name-with-double-colon member-name DOUBLE_COLON STAR member-name 3780 | { 3781 | $$ = $1 + " " +$2 + " " + $3 + " " + $4+ " " + $5; 3782 | } 3783 | | member-name-with-double-colon member-name DOUBLE_COLON TILDE member-name 3784 | { 3785 | $$ = $1 + " " +$2 + " " + $3 + " " + $4+ " " + $5; 3786 | } 3787 | | member-name-with-double-colon member-name DOUBLE_COLON member-name 3788 | { 3789 | $$ = $1 + " " +$2 + " " + $3 + " " + $4; 3790 | } 3791 | | member-name-with-double-colon COMMA STAR member-name 3792 | { 3793 | $$ = $1 + " " +$2 + " " + $3 + " " + $4; 3794 | } 3795 | | member-name-with-double-colon COMMA member-name 3796 | { 3797 | $$ = $1 + " " +$2 + " " + $3; 3798 | } 3799 | | member-name-with-double-colon member-name 3800 | { 3801 | $$ = $1 + " " +$2; 3802 | } 3803 | | type 3804 | { 3805 | $$ = $1; 3806 | } 3807 | ; 3808 | 3809 | member-name 3810 | : variable-declarators 3811 | { 3812 | $$ = $1; 3813 | } 3814 | ; 3815 | 3816 | 3817 | method-body 3818 | : block SEMICOLON 3819 | | block 3820 | | SEMICOLON 3821 | ; 3822 | 3823 | formal-parameter-list 3824 | : fixed-parameters 3825 | { 3826 | $$ = $1; 3827 | } 3828 | | fixed-parameters COMMA STAR parameter-array 3829 | { 3830 | $1.push($4); 3831 | $$ = $1; 3832 | } 3833 | | fixed-parameters COMMA parameter-array 3834 | { 3835 | $1.push($3); 3836 | $$ = $1; 3837 | } 3838 | | parameter-array 3839 | { 3840 | $$ = [ $1 ]; 3841 | } 3842 | ; 3843 | 3844 | fixed-parameters 3845 | : fixed-parameters COMMA STAR fixed-parameter 3846 | { 3847 | $1.push($4); 3848 | $$ = $1; 3849 | } 3850 | | fixed-parameters COMMA fixed-parameter 3851 | { 3852 | $1.push($3); 3853 | $$ = $1; 3854 | } 3855 | | fixed-parameter 3856 | { 3857 | $$ = [ $1 ]; 3858 | } 3859 | ; 3860 | 3861 | IDENTIFIER_WITH_KEYWORD 3862 | : TILDE IDENTIFIER_WITH_KEYWORD 3863 | { 3864 | $$ = $1 + $2; 3865 | } 3866 | | IDENTIFIER_WITH_TEMPLATE 3867 | | ADD 3868 | | REMOVE 3869 | | SET 3870 | | PARAMS 3871 | | DEFAULT 3872 | | METHOD 3873 | | PARAM 3874 | | ASSEMBLY 3875 | | PROPERTY 3876 | | MODULE 3877 | | FIELD 3878 | | TYPE 3879 | | THIS 3880 | | VOLATILE 3881 | | DOTS 3882 | | DELEGATE 3883 | | OPERATOR overloadable-operator 3884 | | OPERATOR 3885 | | REF 3886 | | literal 3887 | ; 3888 | 3889 | fixed-parameter 3890 | : type-with-interr function-pointer OPEN_PARENS formal-parameter-list CLOSE_PARENS 3891 | { 3892 | $$ = { 3893 | "type": $1, 3894 | "name": $2 3895 | }; 3896 | } 3897 | | type-with-interr function-pointer OPEN_PARENS CLOSE_PARENS 3898 | { 3899 | $$ = { 3900 | "type": $1, 3901 | "name": $2 3902 | }; 3903 | } 3904 | | type-with-interr IDENTIFIER_WITH_KEYWORD ASSIGN expression 3905 | { 3906 | $$ = { 3907 | "type": $1, 3908 | "name": $2 3909 | }; 3910 | } 3911 | | CONST STRUCT type-with-interr IDENTIFIER_WITH_KEYWORD 3912 | { 3913 | $$ = { 3914 | "type": $1 + " " + $2 + " " + $3, 3915 | "name": $4 3916 | }; 3917 | } 3918 | | STRUCT type-with-interr IDENTIFIER_WITH_KEYWORD 3919 | { 3920 | $$ = { 3921 | "type": $1 + " " + $2, 3922 | "name": $3 3923 | }; 3924 | } 3925 | | STRUCT type-with-interr 3926 | { 3927 | $$ = { 3928 | "type": $1+ " " + $2 3929 | }; 3930 | } 3931 | | CONST ENUM type-with-interr IDENTIFIER_WITH_KEYWORD 3932 | { 3933 | $$ = { 3934 | "type": $1 + " " + $2 + " " + $3, 3935 | "name": $4 3936 | }; 3937 | } 3938 | | ENUM type-with-interr IDENTIFIER_WITH_KEYWORD 3939 | { 3940 | $$ = { 3941 | "type": $1 + " " + $2, 3942 | "name": $3 3943 | }; 3944 | } 3945 | | ENUM type-with-interr 3946 | { 3947 | $$ = { 3948 | "type": $1 + " " + $2 3949 | }; 3950 | } 3951 | | type-with-interr AMP IDENTIFIER_WITH_KEYWORD 3952 | { 3953 | $$ = { 3954 | "type": $1 + "" + $2, 3955 | "name": $3 3956 | }; 3957 | } 3958 | | type-with-interr IDENTIFIER_WITH_KEYWORD 3959 | { 3960 | $$ = { 3961 | "type": $1, 3962 | "name": $2 3963 | }; 3964 | } 3965 | | type-with-interr 3966 | { 3967 | $$ = { 3968 | "type": $1 3969 | }; 3970 | } 3971 | | fixed-parameter-prefix type-with-interr IDENTIFIER_WITH_KEYWORD ASSIGN expression 3972 | { 3973 | $$ = { 3974 | "type": $1+ " " + $2, 3975 | "name": $3 3976 | }; 3977 | } 3978 | | fixed-parameter-prefix type-with-interr IDENTIFIER_WITH_KEYWORD 3979 | { 3980 | $$ = { 3981 | "type": $1 + " " + $2, 3982 | "name": $3 3983 | }; 3984 | } 3985 | | THIS type-with-interr IDENTIFIER_WITH_KEYWORD 3986 | { 3987 | $$ = { 3988 | "type": $1 + " " + $2, 3989 | "name": $3 3990 | }; 3991 | } 3992 | | fixed-parameter local-rank-specifiers 3993 | { 3994 | $$ = $1; 3995 | } 3996 | ; 3997 | 3998 | fixed-parameter-prefix 3999 | : UNSIGNED 4000 | ; 4001 | 4002 | 4003 | 4004 | parameter-array 4005 | : PARAMS array-type IDENTIFIER_WITH_TEMPLATE 4006 | { 4007 | $$ = { 4008 | "type": $2, 4009 | "name": $3 4010 | }; 4011 | } 4012 | ; 4013 | 4014 | 4015 | property-declaration 4016 | : type-with-interr member-name OPEN_BRACE accessor-declarations CLOSE_BRACE 4017 | { 4018 | $$ = { 4019 | "node": "property", 4020 | "type": $1, 4021 | "name": $2 4022 | }; 4023 | } 4024 | | modifiers type-with-interr member-name OPEN_BRACE accessor-declarations CLOSE_BRACE 4025 | { 4026 | $$ = { 4027 | "node": "property", 4028 | "modifiers": $1, 4029 | "type": $2, 4030 | "name": $3 4031 | }; 4032 | } 4033 | ; 4034 | 4035 | 4036 | operator-declaration 4037 | : modifiers operator-declarator method-body 4038 | { 4039 | $2["node"]= "operator"; 4040 | $2["modifiers"] = $1; 4041 | $$ =$2; 4042 | } 4043 | ; 4044 | 4045 | 4046 | operator-declarator 4047 | : unary-operator-declarator 4048 | { 4049 | $$ = $1; 4050 | } 4051 | | binary-operator-declarator 4052 | { 4053 | $$ = $1; 4054 | } 4055 | ; 4056 | 4057 | unary-operator-declarator 4058 | : type-with-interr OPERATOR overloadable-operator OPEN_PARENS type-with-interr IDENTIFIER_WITH_TEMPLATE CLOSE_PARENS 4059 | { 4060 | $$ = { 4061 | "type": $1, 4062 | "operator": $3, 4063 | "parameter": [{ 4064 | "type": $5, 4065 | "name": $6 4066 | }] 4067 | }; 4068 | } 4069 | ; 4070 | 4071 | overloadable-operator 4072 | : overloadable-unary-operator 4073 | { 4074 | $$ = $1; 4075 | } 4076 | | overloadable-binary-operator 4077 | { 4078 | $$ = $1; 4079 | } 4080 | ; 4081 | 4082 | 4083 | overloadable-unary-operator 4084 | : OP_INC 4085 | | OP_DEC 4086 | | MINUS 4087 | | BANG 4088 | | TILDE 4089 | | PLUS 4090 | | TRUE 4091 | | FALSE 4092 | ; 4093 | 4094 | binary-operator-declarator 4095 | : type-with-interr OPERATOR overloadable-operator OPEN_PARENS type-with-interr IDENTIFIER_WITH_TEMPLATE COMMA type-with-interr IDENTIFIER_WITH_TEMPLATE CLOSE_PARENS 4096 | { 4097 | $$ = { 4098 | "type": $1, 4099 | "operator": $3, 4100 | "parameter": [{ 4101 | "type": $5, 4102 | "name": $6 4103 | }, { 4104 | "type": $8, 4105 | "name": $9 4106 | }] 4107 | }; 4108 | } 4109 | ; 4110 | 4111 | overloadable-binary-operator 4112 | : PLUS 4113 | | MINUS 4114 | | STAR 4115 | | DIV 4116 | | PERCENT 4117 | | AMP 4118 | | BITWISE_OR 4119 | | CARET 4120 | | OP_LEFT_SHIFT 4121 | | RIGHT_SHIFT 4122 | | OP_EQ 4123 | | OP_NE 4124 | | OP_GE 4125 | | OP_LE 4126 | | OP_PTR 4127 | | OP_INC 4128 | | OP_DEC 4129 | | OP_ADD_ASSIGNMENT 4130 | | OP_SUB_ASSIGNMENT 4131 | | OP_MULT_ASSIGNMENT 4132 | | OP_DIV_ASSIGNMENT 4133 | | OP_MOD_ASSIGNMENT 4134 | | OP_AND_ASSIGNMENT 4135 | | OP_OR_ASSIGNMENT 4136 | | OP_XOR_ASSIGNMENT 4137 | | GT 4138 | | LT 4139 | | ASSIGN 4140 | | OPEN_PARENS CLOSE_PARENS 4141 | { 4142 | $$ = $1 + $2; 4143 | } 4144 | ; 4145 | 4146 | 4147 | constructor-declaration 4148 | : constructor-declarator SEMICOLON 4149 | { 4150 | $$ = $1; 4151 | } 4152 | | constructor-declarator method-body 4153 | { 4154 | $$ = $1; 4155 | } 4156 | | modifiers constructor-declarator method-body 4157 | { 4158 | $2["modifiers"] = $1; 4159 | $$ = $2; 4160 | } 4161 | ; 4162 | 4163 | constructor-declarator 4164 | : type OPEN_PARENS formal-parameter-list CLOSE_PARENS ctor-initializer 4165 | { 4166 | $$ = { 4167 | "node": "constructor", 4168 | "name": $1, 4169 | "parameter": $3 4170 | }; 4171 | } 4172 | | type OPEN_PARENS formal-parameter-list CLOSE_PARENS 4173 | { 4174 | $$ = { 4175 | "node": "constructor", 4176 | "name": $1, 4177 | "parameter": $3 4178 | }; 4179 | } 4180 | | type OPEN_PARENS member-name-with-double-colon-list CLOSE_PARENS ctor-initializer 4181 | { 4182 | $$ = { 4183 | "node": "null" 4184 | }; 4185 | } 4186 | | type OPEN_PARENS member-name-with-double-colon-list CLOSE_PARENS 4187 | { 4188 | $$ = { 4189 | "node": "null" 4190 | }; 4191 | } 4192 | | type OPEN_PARENS CLOSE_PARENS ctor-initializer 4193 | { 4194 | $$ = { 4195 | "node": "constructor", 4196 | "name": $1 4197 | }; 4198 | } 4199 | | type OPEN_PARENS CLOSE_PARENS 4200 | { 4201 | $$ = { 4202 | "node": "constructor", 4203 | "name": $1 4204 | }; 4205 | } 4206 | ; 4207 | 4208 | 4209 | 4210 | static-constructor-declaration 4211 | : modifiers IDENTIFIER_WITH_TEMPLATE OPEN_PARENS STAR member-name-with-double-colon CLOSE_PARENS 4212 | { 4213 | $$ = { 4214 | "node": "constructor", 4215 | "modifiers": $1, 4216 | "name": $2 4217 | }; 4218 | } 4219 | | modifiers IDENTIFIER_WITH_TEMPLATE OPEN_PARENS member-name-with-double-colon CLOSE_PARENS 4220 | { 4221 | $$ = { 4222 | "node": "constructor", 4223 | "modifiers": $1, 4224 | "name": $2 4225 | }; 4226 | } 4227 | | modifiers IDENTIFIER_WITH_TEMPLATE OPEN_PARENS CLOSE_PARENS 4228 | { 4229 | $$ = { 4230 | "node": "constructor", 4231 | "modifiers": $1, 4232 | "name": $2 4233 | }; 4234 | } 4235 | | static-constructor-declaration static-constructor-parameter 4236 | { 4237 | $$ = $1; 4238 | } 4239 | | static-constructor-declaration ctor-initializer method-body 4240 | { 4241 | $$ = $1; 4242 | } 4243 | ; 4244 | 4245 | 4246 | 4247 | static-constructor-parameter 4248 | : OPEN_PARENS formal-parameter-list CLOSE_PARENS method-body 4249 | | OPEN_PARENS CLOSE_PARENS method-body 4250 | | method-body 4251 | ; 4252 | 4253 | 4254 | destructor-declaration 4255 | : modifiers TILDE IDENTIFIER_WITH_TEMPLATE OPEN_PARENS formal-parameter-list CLOSE_PARENS destructor-method-body 4256 | { 4257 | $$ = { 4258 | "node": "destructor", 4259 | "modifiers": $1, 4260 | "name": $2 + "" + $3 4261 | }; 4262 | } 4263 | | modifiers EXTERN TILDE IDENTIFIER_WITH_TEMPLATE OPEN_PARENS formal-parameter-list CLOSE_PARENS destructor-method-body 4264 | { 4265 | $$ = { 4266 | "node": "null" 4267 | }; 4268 | } 4269 | | TILDE IDENTIFIER_WITH_TEMPLATE OPEN_PARENS formal-parameter-list CLOSE_PARENS destructor-method-body 4270 | { 4271 | $$ = { 4272 | "node": "destructor", 4273 | "name": $1 + "" + $2 4274 | }; 4275 | } 4276 | | EXTERN TILDE IDENTIFIER_WITH_TEMPLATE OPEN_PARENS formal-parameter-list CLOSE_PARENS destructor-method-body 4277 | { 4278 | $$ = { 4279 | "node": "null" 4280 | }; 4281 | } 4282 | | modifiers TILDE IDENTIFIER_WITH_TEMPLATE OPEN_PARENS CLOSE_PARENS destructor-method-body 4283 | { 4284 | $$ = { 4285 | "node": "destructor", 4286 | "modifiers": $1, 4287 | "name": $2 + "" + $3 4288 | }; 4289 | } 4290 | | modifiers EXTERN TILDE IDENTIFIER_WITH_TEMPLATE OPEN_PARENS CLOSE_PARENS destructor-method-body 4291 | { 4292 | $$ = { 4293 | "node": "null" 4294 | }; 4295 | } 4296 | | TILDE IDENTIFIER_WITH_TEMPLATE OPEN_PARENS CLOSE_PARENS destructor-method-body 4297 | { 4298 | $$ = { 4299 | "node": "destructor", 4300 | "name": $1 + "" + $2 4301 | }; 4302 | } 4303 | | EXTERN TILDE IDENTIFIER_WITH_TEMPLATE OPEN_PARENS CLOSE_PARENS destructor-method-body 4304 | { 4305 | $$ = { 4306 | "node": "null" 4307 | }; 4308 | } 4309 | ; 4310 | 4311 | destructor-method-body 4312 | : method-body 4313 | | ASSIGN variable-initializer SEMICOLON 4314 | ; 4315 | 4316 | 4317 | -------------------------------------------------------------------------------- /grammar/cpp.jisonlex: -------------------------------------------------------------------------------- 1 | %lex 2 | %options flex 3 | 4 | 5 | /* Documentation Comments */ 6 | SINGLE_LINE_DOC_COMMENT '///'{Input_characters}? 7 | 8 | 9 | /* Line Terminators */ 10 | NEW_LINE [\u000D]|[\u000A]|([\u000D][\u000A])|[\u0085]|[\u2029] 11 | 12 | 13 | /* Comments */ 14 | SINGLE_LINE_COMMENT [/]{2} {Input_characters}? /* skip comments */ 15 | Input_characters {Input_character}+ 16 | 17 | /* */ 18 | Input_character [^\u000D\u000A\u0085\u2028\u2029\n] 19 | NEW_LINE_CHARACTER [\u000D]|[\u000A]|[\u0085]|[\u2028]|[\u2029]|'\n' 20 | 21 | 22 | 23 | 24 | 25 | 26 | /* Custome Lexer rules */ 27 | QUOTE '\'' 28 | DOUBLE_QUOTE '"' 29 | BACK_SLASH '\\' 30 | DOUBLE_BACK_SLASH '\\\\' 31 | SHARP '#' 32 | DOT '.' 33 | STAR '*' 34 | 35 | TRUE 'true' 36 | FALSE 'false' 37 | OP_OR '||' 38 | 39 | 40 | /* Unicode character classes */ 41 | UNICODE_CLASS_Zs [\u0020]|[\u00A0]|[\u1680]|[\u180E]|[\u2000]|[\u2001]|[\u2002]|[\u2003]|[\u2004]|[\u2005]|[\u2006]|[\u2008]|[\u2009]|[\u200A]|[\u202F]|[\u3000]|[\u205F] 42 | UNICODE_CLASS_Lu [\u0041-\u005A]|[\u00C0-\u00DE] 43 | UNICODE_CLASS_Ll [\u0061-\u007A] 44 | UNICODE_CLASS_Lt [\u01C5]|[\u01C8]|[\u01CB]|[\u01F2] 45 | UNICODE_CLASS_Lm [\u02B0-\u02EE] 46 | UNICODE_CLASS_Lo [\u01BB]|[\u01C0]|[\u01C1]|[\u01C2]|[\u01C3]|[\u0294] 47 | UNICODE_CLASS_Nl [\u16EE]|[\u16EF]|[\u16F0]|[\u2160]|[\u2161]|[\u2162]|[\u2163]|[\u2164]|[\u2165]|[\u2166]|[\u2167]|[\u2168]|[\u2169]|[\u216A]|[\u216B]|[\u216C]|[\u216D]|[\u216E]|[\u216F] 48 | UNICODE_CLASS_Mn [\u0300]|[\u0301]|[\u0302]|[\u0303]|[\u0304]|[\u0305]|[\u0306]|[\u0307]|[\u0308]|[\u0309]|[\u030A]|[\u030B]|[\u030C]|[\u030D]|[\u030E]|[\u030F]|[\u0310] 49 | UNICODE_CLASS_Mc [\u0903]|[\u093E]|[\u093F]|[\u0940]|[\u0949]|[\u094A]|[\u094B]|[\u094C] 50 | UNICODE_CLASS_Cf [\u00AD]|[\u0600]|[\u0601]|[\u0602]|[\u0603]|[\u06DD] 51 | UNICODE_CLASS_Pc [\u005F]|[\u203F]|[\u2040]|[\u2054]|[\uFE33]|[\uFE34]|[\uFE4D]|[\uFE4E]|[\uFE4F]|[\uFF3F] 52 | UNICODE_CLASS_Nd [\u0030]|[\u0031]|[\u0032]|[\u0033]|[\u0034]|[\u0035]|[\u0036]|[\u0037]|[\u0038]|[\u0039] 53 | 54 | 55 | /* White space */ 56 | WHITESPACE {Whitespace_characters} 57 | Whitespace_characters {Whitespace_character}+ 58 | Whitespace_character {UNICODE_CLASS_Zs}|[\u0009]|[\u000B]|[\u000C]|[\s] 59 | 60 | 61 | /* Unicode Character Escape Sequences */ 62 | Unicode_escape_sequence '\\u' {HEX_DIGIT}{4}|'\\U' {HEX_DIGIT}{8} 63 | 64 | 65 | 66 | Template [<][^=;\|\+\-\"\'\{\\}]*[>]+ 67 | 68 | /* Identifiers */ 69 | IDENTIFIER ({Available_identifier}|'@'{Identifier_or_keyword}) 70 | 71 | /* */ 72 | Available_identifier {Identifier_or_keyword} 73 | Identifier_or_keyword {Identifier_start_character}{Identifier_part_characters}? 74 | Identifier_start_character {Letter_character}|'_' 75 | Identifier_part_characters {Identifier_part_character}+ 76 | Identifier_part_character {Letter_character}|{Decimal_digit_character}|{Connecting_character}|{Combining_character}|{Formatting_character} 77 | 78 | /* */ 79 | Letter_character {UNICODE_CLASS_Lu}|{UNICODE_CLASS_Ll}|{UNICODE_CLASS_Lt}|{UNICODE_CLASS_Lm}|{UNICODE_CLASS_Lo}|{UNICODE_CLASS_Nl} 80 | 81 | /* */ 82 | Combining_character {UNICODE_CLASS_Mn}|{UNICODE_CLASS_Mc} 83 | 84 | /* */ 85 | Decimal_digit_character {UNICODE_CLASS_Nd} 86 | 87 | /* */ 88 | Connecting_character {UNICODE_CLASS_Pc} 89 | 90 | /* */ 91 | Formatting_character {UNICODE_CLASS_Cf} 92 | 93 | 94 | 95 | /* Real Literals */ 96 | REAL_LITERAL {Decimal_digits}{DOT}{Decimal_digits}?{Exponent_part}?{Real_type_suffix}?|{DOT}{Decimal_digits}{Exponent_part}?{Real_type_suffix}?|{Decimal_digits}{Exponent_part}{Real_type_suffix}?|{Decimal_digits}{Real_type_suffix} 97 | Exponent_part 'e'{Sign}?{Decimal_digits}|'E'{Sign}?{Decimal_digits} 98 | Sign '+'|'-' 99 | Real_type_suffix 'F'|'f'|'L'|'l' 100 | 101 | 102 | /* Integer Literals */ 103 | INTEGER_LITERAL {Hexadecimal_integer_literal}|{Decimal_integer_literal} 104 | Decimal_integer_literal {Decimal_digits}{Integer_type_suffix}? 105 | Decimal_digits {DECIMAL_DIGIT}+ 106 | DECIMAL_DIGIT [0-9] 107 | Integer_type_suffix 'ULL'|'UL'|'Ul'|'uL'|'ul'|'LU'|'Lu'|'LL'|'lU'|'lu'|'ll'|'U'|'u'|'L'|'l'|'i64' 108 | Hexadecimal_integer_literal ('0x'{Hex_digits}{Integer_type_suffix}?) | ('0X'{Hex_digits}{Integer_type_suffix}?) 109 | Hex_digits {HEX_DIGIT}+ 110 | HEX_DIGIT [0-9a-fA-F] 111 | 112 | 113 | /* String Literals */ 114 | STRING_LITERAL [L]?{Regular_string_literal}|{Verbatim_string_literal} 115 | Regular_string_literal {DOUBLE_QUOTE}{Regular_string_literal_characters}?{DOUBLE_QUOTE} 116 | Regular_string_literal_characters {Regular_string_literal_character}+ 117 | Regular_string_literal_character {Single_regular_string_literal_character}|{Simple_escape_sequence}|{Hexadecimal_escape_sequence}|{Unicode_escape_sequence}|'\"'|'\\' 118 | 119 | /* */ 120 | Single_regular_string_literal_character [^"\\] 121 | 122 | Verbatim_string_literal '@'{DOUBLE_QUOTE}{Verbatim_string_literal_characters}?{DOUBLE_QUOTE} 123 | Verbatim_string_literal_characters {Verbatim_string_literal_character}+ 124 | Verbatim_string_literal_character {Single_verbatim_string_literal_character}|{Quote_escape_sequence}|'\"'|'\\' 125 | Single_verbatim_string_literal_character [^"] 126 | Quote_escape_sequence '""' 127 | 128 | 129 | /* Character Literals */ 130 | CHARACTER_LITERAL [L]?{QUOTE}{Character}{QUOTE} 131 | Character {Single_character}|{Simple_escape_sequence}|{Hexadecimal_escape_sequence}|{Unicode_escape_sequence} 132 | Single_character [^'] 133 | Simple_escape_sequence '\\\''|'\\"'|{DOUBLE_BACK_SLASH}|'\\0'|'\\a'|'\\b'|'\\f'|'\\n'|'\\r'|'\\t'|'\\v' 134 | Hexadecimal_escape_sequence '\\x'{HEX_DIGIT}{4}|'\\x'{HEX_DIGIT}{3}|'\\x'{HEX_DIGIT}{2}|'\\x'{HEX_DIGIT} 135 | 136 | 137 | /* C.1.10 Pre-processing directives */ 138 | SINGLE_PREPROCESSING [#] {Input_characters}? 139 | 140 | 141 | %s comment 142 | 143 | %% 144 | 145 | ((("/*"))) %{ this.begin('comment'); %} 146 | 147 | [^\*]+ %{ 148 | if (yy.__currentComment) { 149 | yy.__currentComment += "\n" + yytext.trim(); 150 | } else { 151 | yy.__currentComment = yytext.trim(); 152 | } 153 | %} 154 | [\"] /* skip */ 155 | [=] /* skip */ 156 | [\*][=\"']* %{ 157 | var currentChar = yytext; 158 | // console.log("currentChar" + currentChar); 159 | if(currentChar === '*') { 160 | var nxtChar = this._input[0]; // peek into next char without altering lexer's position 161 | //console.log("* match :"+yytext) 162 | //console.log("* match, nxt char:"+nxtChar) 163 | if(nxtChar === '/') 164 | { 165 | //console.log("inside popBlock"+nxtChar); 166 | nxtChar = this.input(); 167 | if(nxtChar.length > 1) 168 | this.unput(2,nxtChar.length); 169 | //console.log("popped state"); 170 | //console.log(this.showPosition()); 171 | this.popState(); 172 | } 173 | } 174 | %} 175 | 176 | {WHITESPACE} /* skip */ 177 | {NEW_LINE_CHARACTER} /* skip */ 178 | 179 | {SINGLE_LINE_COMMENT} /* skip */ 180 | 181 | {SINGLE_LINE_DOC_COMMENT} /* skip */ 182 | {NEW_LINE} /* skip */ 183 | 184 | 185 | 186 | /* Keywords */ 187 | "abstract" return 'ABSTRACT'; 188 | "as" return 'AS'; 189 | "bool" return 'BOOL'; 190 | "break" return 'BREAK'; 191 | "case" return 'CASE'; 192 | "catch" return 'CATCH'; 193 | "char" return 'CHAR'; 194 | "checked" return 'CHECKED'; 195 | "class" return 'CLASS'; 196 | "const" return 'CONST'; 197 | "continue" return 'CONTINUE'; 198 | "decimal" return 'DECIMAL'; 199 | "default" return 'DEFAULT'; 200 | "delegate" return 'DELEGATE'; 201 | "do" return 'DO'; 202 | "double" return 'DOUBLE'; 203 | "else" return 'ELSE'; 204 | "enum" return 'ENUM'; 205 | "explicit" return 'EXPLICIT'; 206 | "extern" return 'EXTERN'; 207 | {FALSE} return 'FALSE'; 208 | "finally" return 'FINALLY'; 209 | "fixed" return 'FIXED'; 210 | "float" return 'FLOAT'; 211 | "for" return 'FOR'; 212 | "foreach" return 'FOREACH'; 213 | "goto" return 'GOTO'; 214 | "if" return 'IF'; 215 | "implicit" return 'IMPLICIT'; 216 | "int" return 'INT'; 217 | "interface" return 'INTERFACE'; 218 | "internal" return 'INTERNAL'; 219 | "long" return 'LONG'; 220 | "namespace" return 'NAMESPACE'; 221 | "new" return 'NEW'; 222 | "null" return 'NULL'; 223 | "operator" return 'OPERATOR'; 224 | "override" return 'OVERRIDE'; 225 | "params" return 'PARAMS'; 226 | "private" return 'PRIVATE'; 227 | "protected" return 'PROTECTED'; 228 | "public" return 'PUBLIC'; 229 | "readonly" return 'READONLY'; 230 | "return" return 'RETURN'; 231 | "sbyte" return 'SBYTE'; 232 | "short" return 'SHORT'; 233 | "sizeof" return 'SIZEOF'; 234 | "stackalloc" return 'STACKALLOC'; 235 | "static" return 'STATIC'; 236 | "struct" return 'STRUCT'; 237 | "switch" return 'SWITCH'; 238 | "this" return 'THIS'; 239 | "throw" return 'THROW'; 240 | {TRUE} return 'TRUE'; 241 | "try" return 'TRY'; 242 | "typeof" return 'TYPEOF'; 243 | "uint" return 'UINT'; 244 | "ulong" return 'ULONG'; 245 | "unchecked" return 'UNCHECKED'; 246 | "unsafe" return 'UNSAFE'; 247 | "ushort" return 'USHORT'; 248 | "using" return 'USING'; 249 | "virtual" return 'VIRTUAL'; 250 | "void" return 'VOID'; 251 | "volatile" return 'VOLATILE'; 252 | "while" return 'WHILE'; 253 | 254 | "assembly" return 'ASSEMBLY'; 255 | "module" return 'MODULE'; 256 | 257 | "field" return 'FIELD'; 258 | "method" return 'METHOD'; 259 | "param" return 'PARAM'; 260 | "property" return 'PROPERTY'; 261 | 262 | 263 | "add" return 'ADD'; 264 | "remove" return 'REMOVE'; 265 | 266 | "partial" return 'PARTIAL'; 267 | "yield" return 'YIELD'; 268 | 269 | "await" return 'AWAIT'; 270 | 271 | "where" return 'WHERE'; 272 | 273 | "delete" return 'DELETE'; 274 | 275 | "friend" return 'FRIEND'; 276 | "typedef" return 'TYPEDEF'; 277 | 278 | "auto" return 'AUTO'; 279 | "register" return 'REGISTER'; 280 | 281 | "inline" return 'INLINE'; 282 | 283 | "signed" return 'SIGNED'; 284 | "unsigned" return 'UNSIGNED'; 285 | 286 | "union" return 'UNION'; 287 | 288 | "asm" return 'ASM'; 289 | 290 | "ref" return 'REF'; 291 | 292 | {Unicode_escape_sequence} return 'Unicode_escape_sequence'; 293 | 294 | {REAL_LITERAL} return 'REAL_LITERAL'; 295 | {INTEGER_LITERAL} return 'INTEGER_LITERAL'; 296 | {STRING_LITERAL} return 'STRING_LITERAL'; 297 | {CHARACTER_LITERAL} return 'CHARACTER_LITERAL'; 298 | 299 | /* Operators And Punctuators*/ 300 | "{" return 'OPEN_BRACE'; 301 | "}" return 'CLOSE_BRACE'; 302 | "[" return 'OPEN_BRACKET'; 303 | "]" return 'CLOSE_BRACKET'; 304 | "(" return 'OPEN_PARENS'; 305 | ")" return 'CLOSE_PARENS'; 306 | "," return 'COMMA'; 307 | ":" return 'COLON'; 308 | ";" return 'SEMICOLON'; 309 | "+" return 'PLUS'; 310 | "-" return 'MINUS'; 311 | {STAR} return 'STAR'; 312 | "/" return 'DIV'; 313 | "%" return 'PERCENT'; 314 | "&" return 'AMP'; 315 | "|" return 'BITWISE_OR'; 316 | "^" return 'CARET'; 317 | "!" return 'BANG'; 318 | "~" return 'TILDE'; 319 | "=" return 'ASSIGN'; 320 | "<" return 'LT'; 321 | ">" return 'GT'; 322 | "?" return 'INTERR'; 323 | "::" return 'DOUBLE_COLON'; 324 | "??" return 'OP_COALESCING'; 325 | "++" return 'OP_INC'; 326 | "--" return 'OP_DEC'; 327 | "&&" return 'OP_AND'; 328 | {OP_OR} return 'OP_OR'; 329 | "->" return 'OP_PTR'; 330 | "=>" return 'OP_DBLPTR'; 331 | "==" return 'OP_EQ'; 332 | "!=" return 'OP_NE'; 333 | "<=" return 'OP_LE'; 334 | ">=" return 'OP_GE'; 335 | "+=" return 'OP_ADD_ASSIGNMENT'; 336 | "-=" return 'OP_SUB_ASSIGNMENT'; 337 | "*=" return 'OP_MULT_ASSIGNMENT'; 338 | "/=" return 'OP_DIV_ASSIGNMENT'; 339 | "%=" return 'OP_MOD_ASSIGNMENT'; 340 | "&=" return 'OP_AND_ASSIGNMENT'; 341 | "|=" return 'OP_OR_ASSIGNMENT'; 342 | "^=" return 'OP_XOR_ASSIGNMENT'; 343 | "<<" return 'OP_LEFT_SHIFT'; 344 | "<<=" return 'OP_LEFT_SHIFT_ASSIGNMENT'; 345 | ">>" return 'RIGHT_SHIFT'; 346 | ">>=" return 'RIGHT_SHIFT_ASSIGNMENT'; 347 | {DOT} return 'DOT' 348 | "..." return 'DOTS' 349 | 350 | {SINGLE_PREPROCESSING} %{ 351 | var r = yytext; 352 | //console.log('#1: '+r); 353 | while(r[r.length-1]=='\\'){ 354 | yylloc.first_line++; 355 | yylloc.last_line++; 356 | temp = ''; 357 | idx = 1; 358 | nxtLine = this._input; 359 | if(this._input[0]!='\n'){ 360 | idx=0; 361 | } 362 | while(this._input[idx]!='\n'){ 363 | temp= temp+this._input[idx]; 364 | idx++; 365 | } 366 | this._input = nxtLine.substring(idx); 367 | r = temp; 368 | 369 | } 370 | 371 | %} 372 | 373 | {Template} %{ 374 | //console.log(this.showPosition()); 375 | var r = yytext; 376 | var forTest3 = ""; 377 | /* 378 | * test 1: check if it is template declaration or LT operator 379 | * test 3: check for && operator. if found, its not a template 380 | * test 2: balanced < and > symbols 381 | */ 382 | var test1=false,test2=false,test3=false, skipTest3= false; 383 | 384 | for(var i=1; i') 409 | balance = balance-1; 410 | if(balance === 0) { 411 | splitPos = i; 412 | break; 413 | } 414 | } 415 | if(balance === 0) { 416 | if(splitPos === (r.length-1)) { 417 | test2 = true; 418 | forTest3 = r; 419 | } 420 | else { 421 | if(r[splitPos+1]=='>') { /* >> left shift operator */ 422 | /* test case /openjdk/hotspot/test/compiler/6711117/Test.java:76 */ 423 | test2 = false; 424 | this.unput(r.substring(1,r.length)); 425 | return 'LT'; 426 | } else { 427 | forTest3 = r.substring(0,splitPos+1); 428 | //console.log("inside test2: "+yytext); 429 | //console.log("test2 unput: "+r.substring(splitPos+1,r.length)); 430 | this.unput(r.substring(splitPos+1,r.length)) 431 | test2 = true; 432 | } 433 | } 434 | } 435 | else { 436 | test2 = false; 437 | this.unput(r.substring(1,r.length)); 438 | return 'LT'; 439 | } 440 | /* Start Test 3 */ 441 | //console.log("test3 start"+forTest3); 442 | if(forTest3.search("&&") === -1) { 443 | test3 = true; 444 | } 445 | else 446 | { 447 | test3 = false; 448 | //console.log("inside test3: "+forTest3); 449 | this.unput(forTest3.substring(1,forTest3.length)); 450 | return 'LT'; 451 | } 452 | if(test1 && test2 && test3) { 453 | yytext = forTest3; 454 | return 'TEMPLATE'; 455 | } 456 | %} 457 | 458 | {IDENTIFIER} return 'IDENTIFIER'; 459 | 460 | 461 | <> return 'EOF'; 462 | 463 | 464 | -------------------------------------------------------------------------------- /grammar/test.cpp: -------------------------------------------------------------------------------- 1 | using namespace std::vector; 2 | 3 | using std::cout; 4 | asm ("ms_codsx0"); 5 | namespace namespace_name { 6 | // code declarations 7 | } 8 | //using std::vector::test::test::test::test::test::test; 9 | //using aa = idset; 10 | //int a = 10; 11 | //auto f = [&tst, temp](int a, char* k) -> void { 12 | // int ak = 10; 13 | // ak += 10; 14 | // a++; 15 | // funcA(ak); 16 | // return; 17 | ////}; 18 | 19 | //function to push the item 20 | //enum day2 ; 21 | /* 22 | inline void push() { 23 | int top; 24 | top++; 25 | for(int a=0, j=10, k = 10- 4; a< 10; a++){ 26 | 27 | } 28 | 29 | } 30 | // 31 | ////function to perform the operation depending on the operator. 32 | int operation(int a,int b,char opr) { 33 | int a = 10; 34 | switch(opr) { 35 | case '+':return a+b; 36 | case '-':return a-b; 37 | case '*':return a*b; 38 | case '/':return a/b; 39 | default: return 0; 40 | } 41 | } 42 | 43 | int getFileLineCount(const char* paramFilename){ 44 | int count; 45 | if(paramFile.is_open()){ 46 | while(paramFile.good()){ 47 | getline(paramFile, line); 48 | count ++; 49 | } 50 | paramFile.close(); 51 | } 52 | return count; 53 | } 54 | 55 | int iscolon(int c){ 56 | if((char)c == ':') 57 | return 1; 58 | else 59 | return 0; 60 | } 61 | 62 | int ispathseperator(int c){ 63 | if((char)c == '/') 64 | return 1; 65 | else 66 | return 0; 67 | } 68 | 69 | int isDot(int c){ 70 | if((char)c == '.') 71 | return 1; 72 | else 73 | return 0; 74 | } 75 | */ -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2018 MKLab. All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | * 22 | */ 23 | 24 | const codeGenerator = require("./code-generator"); 25 | const codeAnalyzer = require("./code-analyzer"); 26 | 27 | function getGenOptions() { 28 | return { 29 | useTab: app.preferences.get("cpp.gen.useTab"), 30 | indentSpaces: app.preferences.get("cpp.gen.indentSpaces"), 31 | useVector: app.preferences.get("cpp.gen.useVector"), 32 | includeHeader: app.preferences.get("cpp.gen.includeHeader"), 33 | genCpp: app.preferences.get("cpp.gen.genCpp"), 34 | }; 35 | } 36 | 37 | function getRevOptions() { 38 | return { 39 | association: app.preferences.get("cpp.rev.association"), 40 | publicOnly: app.preferences.get("cpp.rev.publicOnly"), 41 | typeHierarchy: app.preferences.get("cpp.rev.typeHierarchy"), 42 | packageOverview: app.preferences.get("cpp.rev.packageOverview"), 43 | packageStructure: app.preferences.get("cpp.rev.packageStructure"), 44 | }; 45 | } 46 | 47 | /** 48 | * Command Handler for C++ Generate 49 | * 50 | * @param {Element} base 51 | * @param {string} path 52 | * @param {Object} options 53 | */ 54 | async function _handleGenerate(base, path, options) { 55 | // If options is not passed, get from preference 56 | options = options || getGenOptions(); 57 | // If base is not assigned, popup ElementPicker 58 | if (!base) { 59 | app.elementPickerDialog 60 | .showDialog( 61 | "Select a base model to generate codes", 62 | null, 63 | type.UMLPackage, 64 | ) 65 | .then(async function ({ buttonId, returnValue }) { 66 | if (buttonId === "ok") { 67 | base = returnValue; 68 | // If path is not assigned, popup Open Dialog to select a folder 69 | if (!path) { 70 | var files = await app.dialogs.showOpenDialogAsync( 71 | "Select a folder where generated codes to be located", 72 | null, 73 | null, 74 | { properties: ["openDirectory"] }, 75 | ); 76 | if (files && files.length > 0) { 77 | path = files[0]; 78 | codeGenerator.generate(base, path, options); 79 | } 80 | } else { 81 | codeGenerator.generate(base, path, options); 82 | } 83 | } 84 | }); 85 | } else { 86 | // If path is not assigned, popup Open Dialog to select a folder 87 | if (!path) { 88 | var files = await app.dialogs.showOpenDialogAsync( 89 | "Select a folder where generated codes to be located", 90 | null, 91 | null, 92 | { properties: ["openDirectory"] }, 93 | ); 94 | if (files && files.length > 0) { 95 | path = files[0]; 96 | codeGenerator.generate(base, path, options); 97 | } 98 | } else { 99 | codeGenerator.generate(base, path, options); 100 | } 101 | } 102 | } 103 | 104 | /** 105 | * Command Handler for C++ Reverse 106 | * 107 | * @param {string} basePath 108 | * @param {Object} options 109 | */ 110 | async function _handleReverse(basePath, options) { 111 | // If options is not passed, get from preference 112 | options = getRevOptions(); 113 | // If basePath is not assigned, popup Open Dialog to select a folder 114 | if (!basePath) { 115 | var files = await app.dialogs.showOpenDialogAsync( 116 | "Select Folder", 117 | null, 118 | null, 119 | { 120 | properties: ["openDirectory"], 121 | }, 122 | ); 123 | if (files && files.length > 0) { 124 | basePath = files[0]; 125 | codeAnalyzer.analyze(basePath, options); 126 | } 127 | } 128 | } 129 | 130 | function _handleConfigure() { 131 | app.commands.execute("application:preferences", "cpp"); 132 | } 133 | 134 | function init() { 135 | app.commands.register("cpp:generate", _handleGenerate); 136 | app.commands.register("cpp:reverse", _handleReverse); 137 | app.commands.register("cpp:configure", _handleConfigure); 138 | } 139 | 140 | exports.init = init; 141 | -------------------------------------------------------------------------------- /menus/menu.json: -------------------------------------------------------------------------------- 1 | { 2 | "menu": [ 3 | { 4 | "id": "tools", 5 | "submenu": [ 6 | { 7 | "label": "C++", 8 | "id": "tools.cpp", 9 | "submenu": [ 10 | { "label": "Generate Code...", "id": "tools.cpp.generate", "command": "cpp:generate" }, 11 | { "label": "Reverse Code...", "id": "tools.cpp.reverse", "command": "cpp:reverse" }, 12 | { "type": "separator" }, 13 | { "label": "Configure...", "id": "tools.cpp.configure", "command": "cpp:configure" } 14 | ] 15 | } 16 | ] 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "staruml.cplus", 3 | "title": "C++", 4 | "description": "C++ code generation and reverse engineering.", 5 | "homepage": "https://github.com/staruml/staruml-cpp", 6 | "issues": "https://github.com/staruml/staruml-cpp/issues", 7 | "keywords": [ 8 | "c++" 9 | ], 10 | "version": "0.9.4", 11 | "author": { 12 | "name": "Dongjoon Lee", 13 | "email": "joon1251@gmail.com", 14 | "url": "https://github.com/dongjoon1251" 15 | }, 16 | "license": "MIT", 17 | "engines": { 18 | "staruml": ">=6.0.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /preferences/preference.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "cpp", 3 | "name": "C++", 4 | "schema": { 5 | "cpp.gen": { 6 | "text": "C++ Code Generation", 7 | "type": "section" 8 | }, 9 | "cpp.gen.useTab": { 10 | "text": "Use Tab", 11 | "description": "Use Tab for indentation instead of spaces.", 12 | "type": "check", 13 | "default": false 14 | }, 15 | "cpp.gen.indentSpaces": { 16 | "text": "Indent Spaces", 17 | "description": "Number of spaces for indentation.", 18 | "type": "number", 19 | "default": 4 20 | }, 21 | "cpp.gen.includeHeader": { 22 | "text": "Include default header", 23 | "description": "Include default header.", 24 | "type": "check", 25 | "default": true 26 | }, 27 | "cpp.gen.useVector": { 28 | "text": "Use vector instead of *", 29 | "description": "Use vector<> instead of pointer.", 30 | "type": "check", 31 | "default": true 32 | }, 33 | "cpp.gen.genCpp": { 34 | "text": "Generate *.cpp file", 35 | "description": "Generate cpp file", 36 | "type": "check", 37 | "default": true 38 | }, 39 | "cpp.rev": { 40 | "text": "C++ Reverse Engineering", 41 | "type": "section" 42 | }, 43 | "cpp.rev.association": { 44 | "text": "Use Association", 45 | "description": "Reverse C++ Fields as UML Associations.", 46 | "type": "check", 47 | "default": true 48 | }, 49 | "cpp.rev.publicOnly": { 50 | "text": "Public Only", 51 | "description": "Reverse public members only.", 52 | "type": "check", 53 | "default": false 54 | }, 55 | "cpp.rev.typeHierarchy": { 56 | "text": "Type Hierarchy Diagram", 57 | "description": "Create a type hierarchy diagram for all classes and interfaces", 58 | "type": "check", 59 | "default": true 60 | }, 61 | "cpp.rev.packageOverview": { 62 | "text": "Package Overview Diagram", 63 | "description": "Create overview diagram for each package", 64 | "type": "check", 65 | "default": true 66 | }, 67 | "cpp.rev.packageStructure": { 68 | "text": "Package Structure Diagram", 69 | "description": "Create a package structure diagram for all packages", 70 | "type": "check", 71 | "default": true 72 | } 73 | } 74 | } 75 | --------------------------------------------------------------------------------