#---------------------------------------------------------------------------* # # @file arxmlmetaparser_syntax.galgas # # @section desc File description # # Syntax for AUTOSAR's arxml's meta-data parsing. # # @section copyright Copyright # # Goil OIL compiler, part of Trampoline RTOS # # Trampoline is copyright (c) CNRS, University of Nantes, # Ecole Centrale de Nantes # Trampoline is protected by the French intellectual property law. # # This software is distributed under the GNU Public Licence V2. # Check the LICENSE file in the root directory of Trampoline # # $Date$ # $Rev$ # $Author$ # $URL$ # #---------------------------------------------------------------------------* syntax arxmlmetaparser_syntax (arxmlmetaparser_scanner) { #------------------------------------------------------------------------------ rule !@arxmlMetaClassMap iClassMap ?@bool create_class_file { @arxmlMetaClassMap classMap = {} @arxmlMetaClassGraph classGraph = .emptyGraph # Parse the file and fill the maps !?classMap !?classGraph # Add parameters following the Legacy of each classes fillLegacy(!?classMap !?classGraph) # Compute debug files if requested if create_class_file then # Class file @string classString = "" [classMap display !?classString] [classString writeToFile !"arxml_ecuc_classes.galgas"] # Graph file let @string graphString = [classGraph graphviz] [graphString writeToFile !"arxml_ecuc_graph.dot"] end # Set outputs iClassMap = classMap } rule { $ $?>$ } ############################################################################### # Good link to understand the xml's xsd's format : # http://www.w3schools.com/xml/schema_elements_ref.asp ############################################################################### ## xsd_annotation ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { select $>$ repeat while $ !?classMap !?classGraph !parentClass or $documentation$ !?classMap !?classGraph !parentClass end end # End marker $$ or $/>$ end } ############################################################################### ## xsd_appinfo ## rule ?!@arxmlMetaClassMap unused classMap ?!@arxmlMetaClassGraph unused classGraph ?@lstring unused parentClass { select $>$ # End marker $$ or $/>$ end } ############################################################################### ## xsd_attribute ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { lstringhere(?@lstring attributeType !"") lstringhere(?@lstring attributeName !"") lstringhere(?@lstring attributeRef !"") lstringhere(?@lstring attributePrefix !"") lstringhere(?@lstring attributeUse !"") repeat while $ref$ # Unsed to signal a whitespace will be present after. Unused $=$ $xmlTagValue$ ?attributeRef while $type$ let @lstring fullType $=$ $xmlTagValue$ ?fullType # The Type is either "Prefix:Type" or "Type" if [fullType.string containsCharacter !':'] then let @stringlist parsed = [fullType.string componentsSeparatedByString !":"] @string parsedString [parsed first ?parsedString] attributePrefix.string = parsedString attributePrefix.location = fullType.location [parsed last ?parsedString] attributeType.string = parsedString attributeType.location = fullType.location else attributeType = fullType end while $name$ $=$ $xmlTagValue$ ?attributeName attributeName.string = [attributeName.string stringByReplacingStringByString !"<" !""] attributeName.string = [attributeName.string stringByReplacingStringByString !">" !""] while $use$ $=$ $xmlTagValue$ ?attributeUse end if attributeName.string != "" then let @arxmlMetaAttribute newAttribute = @arxmlMetaAttribute.new{ !attributeName !attributeType !attributePrefix !attributeUse } [!?classMap addClassAttribute !parentClass !newAttribute] end select $>$ repeat while $ !?classMap !?classGraph !parentClass or $simpleType$ !?classMap !?classGraph !parentClass end end # End marker $$ or $/>$ end } ############################################################################### ## xsd_attributeGroup ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { # Parse the attributes @lstring className let @lstring nextParentClass select $name$ # The class does not exists => create it $=$ $xmlTagValue$ ?className # Get the classname from the file className.string = [className.string stringByReplacingStringByString !"<" !""] className.string = [className.string stringByReplacingStringByString !">" !""] lstringhere(?let @lstring desc !"") # The description is filled later if not [classMap hasKey !className] then let @arxmlMetaClass newClass = @arxmlMetaClass.new{ !className !true !{} !{} !{} !{} !desc } [!?classMap insertKey !className !newClass] [!?classGraph addNode !className !className] end nextParentClass = className or $ref$ $=$ $xmlTagValue$ ?let @lstring fullClassName className = fullClassName # The Type is either "Prefix:Type" or "Type" if [fullClassName.string containsCharacter !':'] then let @stringlist parsed = [fullClassName.string componentsSeparatedByString !":"] [parsed last ?let @string parsedString] className.string = parsedString end # Add to the Graph if parentClass.string != className.string then [!?classGraph addEdge !className !parentClass] end nextParentClass = parentClass end select $>$ repeat while $ !?classMap !?classGraph !nextParentClass or $attribute$ !?classMap !?classGraph !nextParentClass or $attributeGroup$ !?classMap !?classGraph !nextParentClass or $choice$ !?classMap !?classGraph !nextParentClass or $sequence$ !?classMap !?classGraph !nextParentClass end end # End marker $$ or $/>$ end } ############################################################################### ## xsd_choice ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { select $>$ repeat while $ !?classMap !?classGraph !parentClass or $choice$ !?classMap !?classGraph !parentClass or $sequence$ !?classMap !?classGraph !parentClass or $element$ !?classMap !?classGraph !parentClass or $group$ !?classMap !?classGraph !parentClass end end # End marker $$ or $/>$ end } ############################################################################### ## xsd_complexType ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { lstringhere(?@lstring complexAbstract !"") lstringhere(?@lstring complexMixed !"") lstringhere(?@lstring complexName !"") repeat while $abstract$ $=$ $xmlTagValue$ ?complexAbstract while $mixed$ $=$ $xmlTagValue$ ?complexMixed while $name$ $=$ $xmlTagValue$ ?complexName complexName.string = [complexName.string stringByReplacingStringByString !"<" !""] complexName.string = [complexName.string stringByReplacingStringByString !">" !""] end if complexName.string == "" then # The complexType node is inside an element node # => We have to create this element's class complexName = parentClass end if not [classMap hasKey !complexName] then lstringhere(?let @lstring desc !"") let @arxmlMetaClass newClass = @arxmlMetaClass.new{ !complexName !false !{} !{} !{} !{} !desc } [!?classMap insertKey !complexName !newClass] [!?classGraph addNode !complexName !complexName] end select $>$ repeat while $ !?classMap !?classGraph !complexName or $attribute$ !?classMap !?classGraph !complexName or $attributeGroup$ !?classMap !?classGraph !complexName or $choice$ !?classMap !?classGraph !complexName or $sequence$ !?classMap !?classGraph !complexName or $group$ !?classMap !?classGraph !complexName or $simpleContent$ !?classMap !?classGraph !complexName end end # End marker $$ or $/>$ end } ############################################################################### ## xsd_documentation ## rule ?!@arxmlMetaClassMap unused classMap ?!@arxmlMetaClassGraph unused classGraph ?@lstring unused parentClass { select $>$ # TODO : Get the description between '>' and '<' # End marker $$ or $/>$ end } ############################################################################### ## xsd_element ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { let @arxmlMetaElement newElement lstringhere(?@lstring elementType !"") lstringhere(?@lstring elementName !"") lstringhere(?@lstring elementMin !"") lstringhere(?@lstring elementMax !"") lstringhere(?@lstring elementPrefix !"") repeat while $maxOccurs$ $=$ $xmlTagValue$ ?elementMax while $minOccurs$ $=$ $xmlTagValue$ ?elementMin while $type$ let @lstring fullType $=$ $xmlTagValue$ ?fullType # The Type is either "Prefix:Type" or "Type" if [fullType.string containsCharacter !':'] then let @stringlist parsed = [fullType.string componentsSeparatedByString !":"] @string parsedString [parsed first ?parsedString] elementPrefix.string = parsedString elementPrefix.location = fullType.location [parsed last ?parsedString] elementType.string = parsedString elementType.location = fullType.location else elementType = fullType end while $name$ $=$ $xmlTagValue$ ?elementName elementName.string = [elementName.string stringByReplacingStringByString !"<" !""] elementName.string = [elementName.string stringByReplacingStringByString !">" !""] end if elementName.string == "" then error .here : "An xsd:element must have a name." end # TODO : We currently don't support the "xsd_choice" statement, so we're not # checking the number of elements inside a choice element by setting the min # to 0 and max to unbounded if not referenced (instead of 1 as required from # xsd). if elementMax.string == "" then lstringhere(?elementMax !"unbounded") end if elementMin.string == "" then lstringhere(?elementMin !"0") end if elementType.string == "" then elementType = elementName else [!?classGraph addEdge !elementType !elementName] end if not [classMap hasKey !elementName] then lstringhere(?let @lstring desc !"") let @arxmlMetaClass newClass = @arxmlMetaClass.new{ !elementName !false !{} !{} !{} !{} !desc } [!?classMap insertKey !elementName !newClass] [!?classGraph addNode !elementName !elementName] end newElement = @arxmlMetaElement.new{!elementName !elementType !elementMin !elementMax !elementPrefix } [!?classMap addClassElement !parentClass !newElement] select $>$ repeat while $ !?classMap !?classGraph !elementName or $complexType$ !?classMap !?classGraph !elementName or $simpleType$ !?classMap !?classGraph !elementName end end # End marker $$ or $/>$ end } ############################################################################### ## xsd_enumeration ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass ?!@arxmlMetaSimpletype restriction { $value$ $=$ $xmlTagValue$ ?let @lstring enumValue [!?restriction addValue !enumValue] select $>$ repeat while $ !?classMap !?classGraph !parentClass end # End marker $$ or $/>$ end } ############################################################################### ## xsd_extension ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { select $>$ repeat while $ !?classMap !?classGraph !parentClass or $attribute$ !?classMap !?classGraph !parentClass or $attributeGroup$ !?classMap !?classGraph !parentClass or $choice$ !?classMap !?classGraph !parentClass or $sequence$ !?classMap !?classGraph !parentClass or $group$ !?classMap !?classGraph !parentClass end end # End marker $$ or $/>$ end } ############################################################################### ## xsd_group ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { # Parse the attributes @lstring className let @lstring nextParentClass select $name$ # The class does not exists => create it $=$ $xmlTagValue$ ?className # Get the classname from the file className.string = [className.string stringByReplacingStringByString !"<" !""] className.string = [className.string stringByReplacingStringByString !">" !""] lstringhere(?let @lstring desc !"") # The description is filled later if not [classMap hasKey !className] then let @arxmlMetaClass newClass = @arxmlMetaClass.new{ !className !false !{} !{} !{} !{} !desc } [!?classMap insertKey !className !newClass] [!?classGraph addNode !className !className] end nextParentClass = className or $ref$ $=$ $xmlTagValue$ ?let @lstring fullClassName className = fullClassName # The Type is either "Prefix:Type" or "Type" if [fullClassName.string containsCharacter !':'] then let @stringlist parsed = [fullClassName.string componentsSeparatedByString !":"] [parsed last ?let @string parsedString] className.string = parsedString end # Add to the Graph if parentClass.string != className.string then [!?classGraph addEdge !className !parentClass] end nextParentClass = parentClass end # End of the attributes select $>$ repeat while $ !?classMap !?classGraph !nextParentClass or $choice$ !?classMap !?classGraph !nextParentClass or $sequence$ !?classMap !?classGraph !nextParentClass or $element$ !?classMap !?classGraph !nextParentClass end end # End marker $$ or $/>$ end } ############################################################################### ## xsd_import ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { select $>$ repeat while $ !?classMap !?classGraph !parentClass end # End marker $$ or $/>$ end } ############################################################################### ## xsd_restriction ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass ?!@arxmlMetaSimpletype restriction { $base$ $=$ $xmlTagValue$ ?let @lstring baseType if "xsd:string" == baseType.string || "xsd:NMTOKEN" == baseType.string || "xsd:NMTOKENS" == baseType.string then [!?restriction setBase !.restrictionString] [!?restriction setType !.restrictionSimple] elsif "xsd:unsignedInt" == baseType.string then [!?restriction setBase !.restrictionUint] [!?restriction setType !.restrictionSimple] elsif "xsd:double" == baseType.string then [!?restriction setBase !.restrictionDouble] [!?restriction setType !.restrictionSimple] else error .here : "Undefined/unimplemented base type " + baseType.string end select $>$ repeat while $ !?classMap !?classGraph !parentClass or $attribute$ $TODO$ !?classMap !?classGraph !parentClass [!?restriction setType !.restrictionUnused] or $attributeGroup$ $TODO$ !?classMap !?classGraph !parentClass [!?restriction setType !.restrictionUnused] or $choice$ $TODO$ !?classMap !?classGraph !parentClass [!?restriction setType !.restrictionUnused] or $sequence$ $TODO$ !?classMap !?classGraph !parentClass [!?restriction setType !.restrictionUnused] or $group$ $TODO$ !?classMap !?classGraph !parentClass [!?restriction setType !.restrictionUnused] or $simpleType$ !?classMap !?classGraph !parentClass [!?restriction setType !.restrictionUnused] or $whiteSpace$ # Asks a string to keep the whitespaces. Ignored. if not [[restriction type] isRestrictionSimple] && not [[restriction base] isRestrictionString] then error .here : "Pattern condition to something not a string." end !?classMap !?classGraph !parentClass or $maxLength$ # Gives a limit to a string. Ignored if not [[restriction type] isRestrictionSimple] && not [[restriction base] isRestrictionString] then error .here : "Pattern condition to something not a string." end !?classMap !?classGraph !parentClass or $pattern$ # Gives a condition to a string. Ignored. if not [[restriction type] isRestrictionSimple] && not [[restriction base] isRestrictionString] then error .here : "Pattern condition to something not a string." end !?classMap !?classGraph !parentClass or $enumeration$ if not [[restriction type] isRestrictionEnum] && not [[restriction type] isRestrictionSimple] then error .here : "Multiple type in a same restriction." end if not [[restriction base] isRestrictionString] then error .here : "Enumeration while restriction base not set to string." end !?classMap !?classGraph !parentClass !?restriction [!?restriction setType !.restrictionEnum] end end # End marker $$ or $/>$ end } ############################################################################### ## xsd_schema ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph { $ $>$ # We create here the root class. It is required because AUTOSAR defines # a global variable for its main node "AUTOSAR". Basically we're going to put # only the AUTOSAR node in this root class and give the root class definition # as an output at the end of the parsing. lstringhere(?let @lstring rootClassName !"root") lstringhere(?let @lstring desc !"Root class containing the main AUTOSAR node") let @arxmlMetaClass rootClass = @arxmlMetaClass.new{ !rootClassName !false !{} !{} !{} !{} !desc } [!?classMap insertKey !rootClassName !rootClass] [!?classGraph addNode !rootClassName !rootClassName] repeat while $ !?classMap !?classGraph !rootClassName or $attribute$ !?classMap !?classGraph !rootClassName or $attributeGroup$ !?classMap !?classGraph !rootClassName or $complexType$ !?classMap !?classGraph !rootClassName or $element$ !?classMap !?classGraph !rootClassName or $group$ !?classMap !?classGraph !rootClassName or $import$ #Unused !?classMap !?classGraph !rootClassName or $simpleType$ !?classMap !?classGraph !rootClassName end end # End marker $$ } ############################################################################### ## xsd_sequence ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { select $>$ repeat while $ !?classMap !?classGraph !parentClass or $choice$ !?classMap !?classGraph !parentClass or $sequence$ !?classMap !?classGraph !parentClass or $element$ !?classMap !?classGraph !parentClass or $group$ !?classMap !?classGraph !parentClass end end # End marker $$ or $/>$ end } ############################################################################### ## xsd_simpleContent ## restriction is never called by the simpleContent in AUTOSAR rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { #lstringhere(?@lstring typeName !"") #@arxmlMetaSimpletype restriction = @arxmlMetaSimpletype.new{ # !typeName # !.restrictionUnused # !.restrictionUndef # !{} # } select $>$ repeat while $ !?classMap !?classGraph !parentClass or $extension$ !?classMap !?classGraph !parentClass # or $restriction$ # !?classMap !?classGraph !parentClass !?restriction end end # End marker $$ or $/>$ end } ############################################################################### ## xsd_simpleType ## rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { # TODO : The case when the simpletype is not called by xsd:schema is not # treated (never happens in AUTOSAR). lstringhere(?@lstring typeName !"") repeat while $name$ $=$ $xmlTagValue$ ?typeName typeName.string = [typeName.string stringByReplacingStringByString !"<" !""] typeName.string = [typeName.string stringByReplacingStringByString !">" !""] end if parentClass.string == "root" && typeName.string == "" then error .here : "The name attribute is required if the simpleType element is" + " a child of the schema element" end @arxmlMetaSimpletype restriction = @arxmlMetaSimpletype.new{ !typeName !.restrictionUnused !.restrictionUndef !{} } if not [classMap hasKey !typeName] then lstringhere(?let @lstring desc !"") let @arxmlMetaClass newClass = @arxmlMetaClass.new{ !typeName !false !{} !{} !{} !{} !desc } [!?classMap insertKey !typeName !newClass] [!?classGraph addNode !typeName !typeName] end select $>$ repeat while $ !?classMap !?classGraph !typeName or $restriction$ !?classMap !?classGraph !typeName !?restriction end end # End marker $$ or $/>$ end #[!?classMap insertKey !typeName !restriction] #[!?classGraph addNode !typeName !typeName] } ############################################################################### ## xsd_maxLength ## This forces the string to have a character number limit ## It is actually ignored. rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { select $>$ repeat while $ !?classMap !?classGraph !parentClass end # End marker $$ or $/>$ end } ############################################################################### ## xsd_pattern ## This forces a pattern for a string. ## Ex : Forces ADDRESS--SIMPLE's string to be written as "0x[0-9][a-z]" ## It is actually ignored. rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { select $>$ repeat while $ !?classMap !?classGraph !parentClass end # End marker $$ or $/>$ end } ############################################################################### ## xsd_whiteSpace ## This forces the string to not ignore the white spaces ## It is actually ignored. rule ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph ?@lstring parentClass { select $>$ repeat while $ !?classMap !?classGraph !parentClass end # End marker $$ or $/>$ end } rule { repeat while $abstract$ $=$ $xmlTagValue$ ?* while $attributeFormDefault$ $=$ $xmlTagValue$ ?* while $attributeRef$ $=$ $xmlTagValue$ ?* while $base$ $=$ $xmlTagValue$ ?* while $category$ $=$ $xmlTagValue$ ?* while $CATEGORY$ $=$ $xmlTagValue$ ?* while $color$ $=$ $xmlTagValue$ ?* while $customType$ $=$ $xmlTagValue$ ?* while $elementFormDefault$ $=$ $xmlTagValue$ ?* while $encoding$ $=$ $xmlTagValue$ ?* while $enforceMinMultiplicity$ $=$ $xmlTagValue$ ?* while $globalElement$ $=$ $xmlTagValue$ ?* while $id$ $=$ $xmlTagValue$ ?* while $latestBindingTime$ $=$ $xmlTagValue$ ?* while $maxOccurs$ $=$ $xmlTagValue$ ?* while $minOccurs$ $=$ $xmlTagValue$ ?* while $mixed$ $=$ $xmlTagValue$ ?* while $name$ $=$ $xmlTagValue$ ?* while $namePlural$ $=$ $xmlTagValue$ ?* while $namespace$ $=$ $xmlTagValue$ ?* while $noteType$ $=$ $xmlTagValue$ ?* while $nsPrefix$ $=$ $xmlTagValue$ ?* while $qualifiedName$ $=$ $xmlTagValue$ ?* while $recommendedPackage$ $=$ $xmlTagValue$ ?* while $ref$ $=$ $xmlTagValue$ ?* while $roleElement$ $=$ $xmlTagValue$ ?* while $roleWrapperElement$ $=$ $xmlTagValue$ ?* while $schemaLocation$ $=$ $xmlTagValue$ ?* while $sequenceOffset$ $=$ $xmlTagValue$ ?* while $source$ $=$ $xmlTagValue$ ?* while $Splitkey$ $=$ $xmlTagValue$ ?* while $Status$ $=$ $xmlTagValue$ ?* while $StatusRevisionBegin$ $=$ $xmlTagValue$ ?* while $targetNamespace$ $=$ $xmlTagValue$ ?* while $type$ $=$ $xmlTagValue$ ?* while $typeElement$ $=$ $xmlTagValue$ ?* while $typeWrapperElement$ $=$ $xmlTagValue$ ?* while $use$ $=$ $xmlTagValue$ ?* while $value$ $=$ $xmlTagValue$ ?* while $version$ $=$ $xmlTagValue$ ?* while $xmlns:AR$ $=$ $xmlTagValue$ ?* while $xmlns:xsd$ $=$ $xmlTagValue$ ?* end } #------------------------------------------------------------------------------ } proc lstringhere !@lstring string ?@string value { string = @lstring.new{!value !@location.here{}} } proc fillLegacy ?!@arxmlMetaClassMap classMap ?!@arxmlMetaClassGraph classGraph { let @stringlist sortedInfoList = [classGraph keyList] for (@string sClassName) in sortedInfoList do lstringhere(?let @lstring lClassName !sClassName) @arxmlMetaClass lClass [classMap searchKey !lClassName ?lClass] # Get successors @lstringlist fromList = {} [!?fromList insertAtIndex ![lClass name] !0] let @stringset empty = .emptySet let @lstringlist successorList = [classGraph accessibleNodesFrom !fromList !empty] # Add this class's elements and attributes to each of the successors class [!?lClass legacyAddParameters !?classMap !successorList] end }