// Declaration -> BuiltInType Identifier | BuiltInType Identifier ConstantDeclaration | BuiltInType ArrayDeclaration Identifier // Declaration -> DefinedType Identifier | DefinedType ArrayDeclaration Identifier // Declaration -> Header Identifier private void Declaration() { string declaration = ""; // Type MessageToken peeked = Peek(); string type = ""; bool canHaveConstDecl = false; declaration += MsgAutoGenUtilities.TWO_TABS + "public "; if (PeekType(MessageTokenType.BuiltInType)) { type = builtInTypeMapping[MatchByType(MessageTokenType.BuiltInType)]; if (!type.Equals("Time") && !type.Equals("Duration")) { // Time and Duration can't have constant declaration // See <wiki.ros.org/msg> canHaveConstDecl = true; } else { // Need to import Standard imports.Add("Std"); } } else if (PeekType(MessageTokenType.DefinedType)) { type = MatchByType(MessageTokenType.DefinedType); string[] hierarchy = type.Split(new char[] { '/', '\\' }); // Assume type can only be either: // Type // package/Type switch (hierarchy.Length) { case 1: break; case 2: if (hierarchy[0].Equals("") || hierarchy[1].Equals("")) { throw new MessageParserException( "Invalid field type '" + type + "'. + " + "(" + inFilePath + ":" + lineNum + ")"); } string package = MsgAutoGenUtilities.ResolvePackageName(hierarchy[0]); // Do not add package name if exists in current namespace type = package.Equals(rosPackageNamespace) ? hierarchy[1] : package + "." + hierarchy[1]; break; default: throw new MessageParserException( "Invalid field type '" + type + "'. + " + "(" + inFilePath + ":" + lineNum + ")"); } } else { type = MatchByType(MessageTokenType.Header); if (PeekType(MessageTokenType.FixedSizeArray) || PeekType(MessageTokenType.VariableSizeArray)) { Warn( "By convention, there is only one header for each message." + "(" + inFilePath + ":" + lineNum + ")"); } if (PeekType(MessageTokenType.Identifier) && !Peek().content.Equals("header")) { Warn( "By convention, a ros message Header will be named 'header'. '" + Peek().content + "'. (" + inFilePath + ":" + lineNum + ")"); } imports.Add("Std"); } // Array Declaration int arraySize = -1; if (PeekType(MessageTokenType.FixedSizeArray)) { type += "[]"; canHaveConstDecl = false; arraySize = int.Parse(MatchByType(MessageTokenType.FixedSizeArray)); } if (PeekType(MessageTokenType.VariableSizeArray)) { type += "[]"; canHaveConstDecl = false; MatchByType(MessageTokenType.VariableSizeArray); arraySize = 0; } // Identifier string identifier = MatchByType(MessageTokenType.Identifier); // Check for duplicate declaration if (symbolTable.ContainsKey(identifier)) { throw new MessageParserException( "Field '" + identifier + "' at " + inFilePath + ":" + lineNum + " already declared!"); } // Check if identifier is a ROS message built-in type if (builtInTypeMapping.ContainsKey(identifier) && identifier.Equals("time") && identifier.Equals("duration")) { throw new MessageParserException( "Invalid field identifier '" + identifier + "' at " + inFilePath + ":" + lineNum + ". '" + identifier + "' is a ROS message built-in type."); } // Check if identifier is a C# keyword if (MsgAutoGenUtilities.CSharpKeywords.Contains(identifier)) { Warn( "'" + identifier + "' is a C# keyword. It can be accessed under the name @" + identifier + "." + "(" + inFilePath + ":" + lineNum + ")"); identifier = "@" + identifier; } symbolTable.Add(identifier, type); // Array declaration table if (arraySize > -1) { arraySizes.Add(identifier, arraySize); } // Constant Declaration if (PeekType(MessageTokenType.ConstantDeclaration)) { if (canHaveConstDecl) { declaration += "const " + type + " " + identifier + " = "; declaration += ConstantDeclaration(type); constants.Add(identifier); } else { throw new MessageParserException( "Type " + type + "' at " + inFilePath + ":" + lineNum + " cannot have constant declaration"); } } else { declaration += type + " " + identifier + ";\n"; } body += declaration; }
public static string GetMessageOutFolder(string outPath, string rosPackageName) { return(Path.Combine(outPath, MsgAutoGenUtilities.ResolvePackageName(rosPackageName))); }