Exemplo n.º 1
0
        public MessageParser(List <MessageToken> tokens, string outPath, string rosPackageName, string type, Dictionary <string, string> builtInTypeMapping, Dictionary <string, string> builtInTypesDefaultInitialValues, string className = "", string rosMsgName = "")
        {
            this.tokens = tokens;

            this.inFilePath = tokens[0].content;
            this.inFileName = Path.GetFileNameWithoutExtension(inFilePath);

            this.rosPackageName = rosPackageName;

            if (className.Equals(""))
            {
                this.className = MsgAutoGenUtilities.CapitalizeFirstLetter(inFileName);
            }
            else
            {
                this.className = className;
            }

            if (rosMsgName.Equals(""))
            {
                this.rosMsgName = MsgAutoGenUtilities.CapitalizeFirstLetter(inFileName);
            }
            else
            {
                this.rosMsgName = rosMsgName;
            }


            this.outPath     = outPath;
            this.outFilePath = Path.Combine(outPath, type);

            this.tokens.RemoveAt(0);

            this.builtInTypeMapping = builtInTypeMapping;
            this.builtInTypesDefaultInitialValues = builtInTypesDefaultInitialValues;
        }
Exemplo n.º 2
0
        // 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]);
                    imports.Add(package);
                    type = 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.");
            }

#if NETFRAMEWORK
            CodeDomProvider provider = CodeDomProvider.CreateProvider("C#");
            // Check if identifier is a C# keyword
            if (!provider.IsValidIdentifier(identifier))
            {
                Warn(
                    "'" + identifier + "' is a C# keyword. We have appended \"_\" at the front to avoid C# compile-time issues." +
                    "(" + inFilePath + ":" + lineNum + ")");
                declaration = MsgAutoGenUtilities.TWO_TABS + "[JsonProperty(\"" + identifier + "\")]\n" + declaration;
                identifier  = "_" + identifier;
            }
#else
            Warn(
                "'CodeDomProvider class might not exist on your platform. We did not check whether " + identifier + "' is a C# keyword." +
                "(" + inFilePath + ":" + lineNum + ")");
#endif

            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 + MsgAutoGenUtilities.PROPERTY_EXTENSION + "\n";
            }
            body += declaration;
        }
Exemplo n.º 3
0
        public void WrapAction()
        {
            string wrapperName = inFileName + "Action";

            string outPath = Path.Combine(this.outPath, wrapperName + ".cs");

            string imports =
                "using Newtonsoft.Json;\n\n";

            symbolTable = new Dictionary <string, string>();

            using (StreamWriter writer = new StreamWriter(outPath, false))
            {
                // Write block comment
                writer.Write(MsgAutoGenUtilities.BLOCK_COMMENT + "\n");

                // Write imports
                writer.Write(imports);

                // Write namespace
                writer.Write(
                    "namespace RosSharp.RosBridgeClient.MessageTypes." + MsgAutoGenUtilities.ResolvePackageName(rosPackageName) + "\n" +
                    "{\n"
                    );

                // Write class declaration
                string[] genericParams = new string[] {
                    inFileName + "ActionGoal",
                    inFileName + "ActionResult",
                    inFileName + "ActionFeedback",
                    inFileName + "Goal",
                    inFileName + "Result",
                    inFileName + "Feedback"
                };
                writer.Write(
                    ONE_TAB + "public class " + wrapperName + " : Action<" + string.Join(", ", genericParams) + ">\n" +
                    ONE_TAB + "{\n"
                    );

                // Write ROS package name
                writer.Write(
                    TWO_TABS + "[JsonIgnore]\n" +
                    TWO_TABS + "public const string RosMessageName = \"" + rosPackageName + "/" + wrapperName + "\";\n"
                    );

                // Record variables
                // Action Goal
                symbolTable.Add("action_goal", wrapperName + "Goal");
                // Action Result
                symbolTable.Add("action_result", wrapperName + "Result");
                //Action Feedback
                symbolTable.Add("action_feedback", wrapperName + "Feedback");

                // Write default value constructor
                writer.Write("\n" + GenerateDefaultValueConstructor(wrapperName) + "\n");

                // Close class
                writer.Write(ONE_TAB + "}\n");
                // Close namespace
                writer.Write("}\n");
            }
        }
Exemplo n.º 4
0
        public void Parse()
        {
            // If outpath doesn't exist, mkdir
            if (!Directory.Exists(outFilePath))
            {
                Directory.CreateDirectory(outFilePath);
            }
            // Append filename
            this.outFilePath = Path.Combine(this.outFilePath, this.className + ".cs");

            using (StreamWriter writer = new StreamWriter(outFilePath, false))
            {
                writer.Write(MsgAutoGenUtilities.BLOCK_COMMENT + "\n");

                // Message -> Lines
                // Lines -> Line Lines | e
                while (!IsEmpty())
                {
                    Line();
                }

                // Write imports
                writer.Write(GenerateImports());

                // Write namespace
                writer.Write(
                    "namespace RosSharp.RosBridgeClient.MessageTypes." + MsgAutoGenUtilities.ResolvePackageName(rosPackageName) + "\n" +
                    "{\n"
                    );

                // Write class declaration
                writer.Write(
                    MsgAutoGenUtilities.ONE_TAB + "public class " + className + " : Message\n" +
                    MsgAutoGenUtilities.ONE_TAB + "{\n"
                    );

                // Write ROS package name
                writer.Write(MsgAutoGenUtilities.TWO_TABS + "[JsonIgnore]\n");
                writer.Write(MsgAutoGenUtilities.TWO_TABS + "public const string RosMessageName = \"" + rosPackageName + "/" + rosMsgName + "\";\n\n");

                // Write body
                writer.Write(body);
                writer.Write("\n");

                // Write constructors
                writer.Write(GenerateDefaultValueConstructor());
                if (symbolTable.Count != 0 && !new HashSet <string>(symbolTable.Keys).SetEquals(constants))
                {
                    writer.Write("\n");
                    writer.Write(GenerateParameterizedConstructor());
                }

                // Close class
                writer.Write(MsgAutoGenUtilities.ONE_TAB + "}\n");
                // Close namespace
                writer.Write("}\n");

                writer.Flush();
                writer.Close();
            }
        }