コード例 #1
0
        public UavcanTypeMeta ParseMeta(string path)
        {
            var name  = Path.GetFileName(path);
            var match = _fileNameRegex.Match(name);

            if (!match.Success)
            {
                throw new Exception($"Invalid file name [{path}]; expected pattern: [<default-dtid>.]<short-type-name>.[<major-version>.<minor-version>.]" + DsdlExtension);
            }
            var meta = new UavcanTypeMeta();

            if (match.Groups["DTID"].Success)
            {
                meta.DefaultDTID = int.Parse(match.Groups["DTID"].Value);
            }
            if (match.Groups["VER"].Success)
            {
                meta.Version = Version.Parse(match.Groups["VER"].Value);
            }
            meta.Namespace = GetNamespace(path);
            meta.Name      = match.Groups["NAME"].Value;
            return(meta);
        }
コード例 #2
0
        static void ProcessLineTokens(UavcanTypeMeta meta, CompositeDsdlType type, string[] tokens)
        {
            if (tokens.Length < 1)
            {
                throw new Exception("Invalid attribute definition.");
            }

            int offset   = 0;
            var castMode = CastMode.Saturated;

            switch (tokens[0])
            {
            case "saturated":
                offset++;
                break;

            case "truncated":
                offset++;
                castMode = CastMode.Truncated;
                break;
            }

            string attrTypeName, attrName;

            switch (tokens.Length - offset)
            {
            case 0:
            case 1 when(!tokens[0].StartsWith("void")):
                throw new Exception("Invalid attribute definition.");

            case 1:
                attrTypeName = tokens[offset];
                attrName     = null;
                offset      += 1;
                break;

            default:
                attrTypeName = tokens[offset];
                attrName     = tokens[offset + 1];
                offset      += 2;
                break;
            }

            var attrType = ParseType(meta.Namespace, attrTypeName, castMode);

            switch (attrType)
            {
            case VoidDsdlType _:
                break;

            default:
                ValidateAttributeName(attrName);
                break;
            }

            switch (tokens.Length - offset)
            {
            case 0:
                var field = new DsdlField
                {
                    Name = attrName,
                    Type = attrType,
                };
                type.AddMember(field);
                if (attrName != null)
                {
                    type.Members.Add(attrName, field);
                }
                break;

            case 1:
                throw new Exception("Constant assignment expected.");

            default:
                if (tokens[offset] != "=")
                {
                    throw new Exception("Constant assignment expected.");
                }
                var expression = string.Join(" ", tokens, offset + 1, tokens.Length - offset - 1);
                var constant   = CreateConstant(attrType, attrName, expression);
                type.AddMember(constant);
                if (attrName != null)
                {
                    type.Members.Add(attrName, constant);
                }
                break;
            }
        }
コード例 #3
0
        public static IUavcanType Parse(TextReader reader, UavcanTypeMeta meta)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            if (meta == null)
            {
                throw new ArgumentNullException(nameof(meta));
            }

            ValidateTypeFullName(meta.FullName);

            IUavcanType result       = null;
            var         compoundType = new CompositeDsdlType();

            int    lineCounter = 0;
            string line;

            while ((line = reader.ReadLine()) != null)
            {
                lineCounter++;

                line = SkipComment(line).Trim();
                if (string.IsNullOrEmpty(line))
                {
                    continue;
                }

                try
                {
                    if (line == "---")
                    {
                        if (result != null)
                        {
                            throw new Exception("Duplicate response mark.");
                        }

                        result = new ServiceType
                        {
                            Meta    = meta,
                            Request = compoundType,
                        };

                        compoundType = new CompositeDsdlType();
                    }
                    else if (line == "@union")
                    {
                        if (compoundType.IsUnion)
                        {
                            throw new Exception("Data structure has already been declared as union.");
                        }
                        compoundType.SetIsUnion(true);
                    }
                    else
                    {
                        var tokens = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        ProcessLineTokens(meta, compoundType, tokens);
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception($"Cannot parse line #{lineCounter}: '{line}'.", ex);
                }
            }

            if (result == null)
            {
                result = new MessageType(compoundType)
                {
                    Meta = meta,
                };
            }
            else if (result is ServiceType st)
            {
                st.Response = compoundType;
            }
            else
            {
                throw new InvalidOperationException();
            }

            ValidateDTID(result);
            ValidateUnion(result);

            return(result);
        }