Skip to content

Commit e059b51

Browse files
committed
Implement idl parser (in progress)
Signed-off-by: Yangbo Long <[email protected]>
1 parent 1f6a231 commit e059b51

File tree

16 files changed

+3243
-1
lines changed

16 files changed

+3243
-1
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ if(MSVC OR MSVC_IDE)
6262
# C4715: 'Test': not all control paths return a value
6363
# C5038 data member 'member1' will be initialized after data member 'member2'
6464
# C4100 'identifier' : unreferenced formal parameter (matches clang -Wunused-lambda-capture)
65-
add_compile_options(/w34101 /w34189 /w34555 /w34715 /w35038 /w44100)
65+
add_compile_options(/w34101 /w34189 /w34555 /w34715 /w35038 /w44100 /bigobj)
6666

6767
if(EPROSIMA_BUILD)
6868
string(REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
cmake_minimum_required(VERSION 3.20)
16+
17+
project(IdlParserExample VERSION 1 LANGUAGES CXX)
18+
19+
# Find requirements
20+
if(NOT fastcdr_FOUND)
21+
find_package(fastcdr 2 REQUIRED)
22+
endif()
23+
24+
if(NOT fastdds_FOUND)
25+
find_package(fastdds 3 REQUIRED)
26+
endif()
27+
28+
# Check C++11
29+
include(CheckCXXCompilerFlag)
30+
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
31+
check_cxx_compiler_flag(-std=c++11 SUPPORTS_CXX11)
32+
check_cxx_compiler_flag(-std=c++11 SUPPORTS_CXX11)
33+
if(NOT SUPPORTS_CXX11)
34+
message(FATAL_ERROR "Compiler doesn't support C++11")
35+
endif()
36+
endif()
37+
38+
message(STATUS "Configuring IDL parser example...")
39+
file(GLOB DDS_IDL_PARSER_EXAMPLE_SOURCES_CPP "*.cpp")
40+
41+
include_directories(
42+
../../../../thirdparty/taocpp-pegtl/
43+
../../../../src/cpp/fastdds/xtypes/dynamic_types/
44+
)
45+
46+
add_executable(IdlParserExample
47+
${DDS_IDL_PARSER_EXAMPLE_SOURCES_CPP})
48+
49+
target_compile_definitions(IdlParserExample PRIVATE
50+
$<$<AND:$<NOT:$<BOOL:${WIN32}>>,$<STREQUAL:"${CMAKE_BUILD_TYPE}","Debug">>:__DEBUG>
51+
$<$<BOOL:${INTERNAL_DEBUG}>:__INTERNALDEBUG> # Internal debug activated.
52+
)
53+
54+
# Put executable in directory where CMake files are being generated
55+
if(MSVC)
56+
set_target_properties(IdlParserExample PROPERTIES
57+
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR})
58+
endif()
59+
60+
# Copy IDL files
61+
configure_file(
62+
${PROJECT_SOURCE_DIR}/idl/test01.idl
63+
${PROJECT_BINARY_DIR}/idl/test01.idl
64+
COPYONLY)
65+
configure_file(
66+
${PROJECT_SOURCE_DIR}/idl/test02.idl
67+
${PROJECT_BINARY_DIR}/idl/test02.idl
68+
COPYONLY)
69+
configure_file(
70+
${PROJECT_SOURCE_DIR}/idl/test03.idl
71+
${PROJECT_BINARY_DIR}/idl/test03.idl
72+
COPYONLY)
73+
configure_file(
74+
${PROJECT_SOURCE_DIR}/idl/test04.idl
75+
${PROJECT_BINARY_DIR}/idl/test04.idl
76+
COPYONLY)
77+
configure_file(
78+
${PROJECT_SOURCE_DIR}/idl/include/test_include.idl
79+
${PROJECT_BINARY_DIR}/idl/include/test_include.idl
80+
COPYONLY)
81+
82+
target_link_libraries(IdlParserExample fastdds fastcdr)
83+
install(TARGETS IdlParserExample
84+
RUNTIME DESTINATION examples/cpp/dds/IdlParserExample/${BIN_INSTALL_DIR})
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/**
16+
* @file IdlParser_main.cpp
17+
*
18+
*/
19+
20+
#define FASTDDS_ENFORCE_LOG_INFO
21+
22+
#include <DynamicTypeBuilderFactoryImpl.hpp>
23+
#include <fastrtps/log/Log.h>
24+
25+
#include <iostream>
26+
27+
using namespace eprosima::fastdds::dds;
28+
using eprosima::fastdds::dds::Log;
29+
30+
int main(
31+
int argc,
32+
char** argv)
33+
{
34+
Log::SetVerbosity(Log::Kind::Info);
35+
Log::SetCategoryFilter(std::regex("IDLPARSER"));
36+
37+
std::cout << "Processing forward declarations:" << std::endl;
38+
std::string test00 =
39+
R"(
40+
struct StructDcl;
41+
union UnionDcl;
42+
)";
43+
DynamicType::_ref_type fwd_dcl_type = DynamicTypeBuilderFactory::get_instance()->create_type_w_idl(test00)->build();
44+
if (nullptr != fwd_dcl_type)
45+
{
46+
EPROSIMA_LOG_INFO(IDLPARSER, "Succeeded to create DynamicType from IDL: " << test00);
47+
}
48+
else
49+
{
50+
EPROSIMA_LOG_ERROR(IDLPARSER, "Failed to create DynamicType from IDL: " << test00);
51+
}
52+
53+
// std::cout << "Processing literals, expressions, and consts:" << std::endl;
54+
// std::string test01 =
55+
// R"(
56+
// // boolean literals in IDL are case sensitive and should be exactly TRUE or FALSE
57+
// const boolean C_BOOL = TRUE;
58+
// const string<100> C_STR = "hello";
59+
// const int32 C_LITERALS1 = (0x5 | (4 + 3)) + (4 << 1) * 2; // 23
60+
// const int32 C_LITERALS2 = (02 + 0x1) * 2; // 6
61+
// const int32 C_LITERALS3 = 4 / ( 07 & 0x2 ); // 2
62+
// const int32 C_LITERALS4 = -(5 * ( 03 + 0xF )); // -90
63+
// const int32 C_LITERALS5 = 0xf0 & ~(4 * ( 0x7 - 02 )); // 224
64+
// const int32 C_LITERALS6 = (0x7 | 0x9) & ~(6 * ( 024 - 5 )); // 5
65+
// const float C_LITERALS7 = (2 + 4) / 3.0d; /* 2.0 */
66+
// const float C_LITERALS8 = (2e0 + 4) / 3.0d; /* 2.0 */
67+
// )";
68+
// idl::Context context01 = idl::parse(test01);
69+
70+
// std::cout << "Processing IDL string:" << std::endl;
71+
// std::string test02 =
72+
// R"(
73+
// struct InnerType
74+
// {
75+
// uint32 im1;
76+
// float im2;
77+
// };
78+
// )";
79+
// idl::Context context02 = idl::parse(test02);
80+
81+
// std::cout << "Processing IDL file:" << std::endl;
82+
// idl::Context context03 = idl::parse_file("idl/test02.idl");
83+
84+
// std::string test04 =
85+
// R"(
86+
// enum e_test { a, b, c };
87+
// )";
88+
// idl::Context context04 = idl::parse(test04);
89+
90+
// std::string test05 =
91+
// R"(
92+
// struct Test05
93+
// {
94+
// long my_long;
95+
// short my_short;
96+
// long long my_llong;
97+
// int32 my_int;
98+
// unsigned short my_ushort;
99+
// unsigned long my_ulong;
100+
// long double my_ldouble;
101+
// float my_float;
102+
// double my_double;
103+
// };
104+
// )";
105+
// idl::Context context05 = idl::parse(test05);
106+
107+
// std::string test06 =
108+
// R"(
109+
// struct Point {
110+
// float x;
111+
// float y;
112+
// float z;
113+
// };
114+
// typedef Point PointAlias;
115+
// typedef Point PointArrayOf10[ 10 /**/];
116+
// typedef PointAlias TwoDimPointArray[5][3];
117+
// )";
118+
// idl::Context context06 = idl::parse(test06);
119+
120+
// std::string test07 =
121+
// R"(
122+
// union MyUnion switch (int32) {
123+
// case 0:
124+
// case 1:
125+
// long myLong;
126+
// case 2:
127+
// double myDouble;
128+
// default:
129+
// char myChar;
130+
// };
131+
// )";
132+
// idl::Context context07 = idl::parse(test07);
133+
134+
std::string idl_spec =
135+
R"(
136+
struct InnerType
137+
{
138+
uint32 im1;
139+
float im2;
140+
};
141+
)";
142+
143+
DynamicType::_ref_type inner_type = DynamicTypeBuilderFactory::get_instance()->create_type_w_idl(idl_spec)->build();
144+
if (nullptr != inner_type)
145+
{
146+
EPROSIMA_LOG_INFO(IDLPARSER, "Succeeded to create DynamicType from IDL: " << idl_spec);
147+
}
148+
else
149+
{
150+
EPROSIMA_LOG_ERROR(IDLPARSER, "Failed to create DynamicType from IDL: " << idl_spec);
151+
}
152+
153+
// idl::Context context = idl::parse(idl_spec);
154+
// v1_3::DynamicType inner = context.module().structure("InnerType");
155+
156+
// v1_3::DynamicTypeBuilderFactory& factory = v1_3::DynamicTypeBuilderFactory::get_instance();
157+
// v1_3::DynamicTypeBuilder_ptr builder = factory.create_struct_type();
158+
// builder->set_name("OuterType");
159+
// builder->add_member(0, "om1", factory.get_string_type());
160+
// auto outer = builder->build();
161+
162+
// idl::Module root;
163+
// idl::Module& submod_a = root.create_submodule("a");
164+
// idl::Module& submod_b = root.create_submodule("b");
165+
// idl::Module& submod_aa = submod_a.create_submodule("a");
166+
// submod_aa.structure(std::move(const_cast<v1_3::DynamicType&>(*outer)));
167+
// submod_b.structure(inner);
168+
// /*
169+
// root
170+
// \_a
171+
// | \_ a _ OuterType
172+
// |
173+
// \_ b _ InnerType
174+
// */
175+
// std::cout << std::boolalpha;
176+
// std::cout << "Does a::a::OuterType exists?: " << root.has_structure("a::a::OuterType") << std::endl;
177+
// std::cout << "Does ::InnerType exists?: " << root.has_structure("::InnerType") << std::endl;
178+
// std::cout << "Does InnerType exists?: " << root.has_structure("InnerType") << std::endl;
179+
// std::cout << "Does OuterType exists?: " << root.has_structure("OuterType") << std::endl;
180+
// std::cout << "Does ::b::InnerType exists?: " << root.has_structure("::b::InnerType") << std::endl;
181+
// std::cout << "Does b::InnerType exists?: " << root.has_structure("b::InnerType") << std::endl;
182+
183+
// v1_3::DynamicData* outer_data = v1_3::DynamicDataFactory::get_instance()->create_data(
184+
// std::make_shared<v1_3::DynamicType>(root["a"]["a"].structure("OuterType"))
185+
// ); // ::a::a::OuterType
186+
// v1_3::MemberId member_id = outer_data->get_member_id_by_name("om1");
187+
// outer_data->set_string_value("This is a string.", member_id);
188+
189+
// std::string scope_inner_type = inner.get_name(); // b::InnerType
190+
// v1_3::DynamicData* inner_data = v1_3::DynamicDataFactory::get_instance()->create_data(
191+
// std::make_shared<v1_3::DynamicType>(root.structure(scope_inner_type))
192+
// );
193+
// inner_data->set_uint32_value(32u, inner_data->get_member_id_by_name("im1"));
194+
// inner_data->set_float32_value(3.14159265f, inner_data->get_member_id_by_name("im2"));
195+
196+
Log::Flush();
197+
Log::Reset();
198+
199+
return 0;
200+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
module include
4+
{
5+
struct TestInclude
6+
{
7+
string my_string;
8+
};
9+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const float C_FLOAT = 3.141592;
2+
3+
struct Test01
4+
{
5+
long my_long;
6+
short my_short;
7+
long long my_long_long;
8+
};
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include "include/test_include.idl"
2+
3+
struct Test02
4+
{
5+
include::TestInclude my_include;
6+
};
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include <test_include.idl>
2+
3+
struct Test03
4+
{
5+
include::TestInclude my_include;
6+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <test_include.idl>
2+
#include "test03.idl"
3+
4+
struct Test04
5+
{
6+
include::TestInclude my_include;
7+
Test03 my_test03;
8+
};

include/fastdds/dds/xtypes/dynamic_types/DynamicTypeBuilderFactory.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ class DynamicTypeBuilderFactory : public std::enable_shared_from_this<DynamicTyp
145145
FASTDDS_EXPORTED_API virtual traits<DynamicTypeBuilder>::ref_type create_bitmask_type(
146146
uint32_t bound) = 0;
147147

148+
/*!
149+
* Creates a new @ref DynamicTypeBuilder reference based on the given IDL string.
150+
* @param[in] idl representing an IDL string to be parsed.
151+
* @return New @ref DynamicTypeBuilder reference. Nil reference returned in error case.
152+
*/
153+
FASTDDS_EXPORTED_API virtual traits<DynamicTypeBuilder>::ref_type create_type_w_idl(
154+
const std::string& idl) = 0;
155+
148156
/*!
149157
* Creates a new @ref DynamicTypeBuilder reference by parsing the type description at the given URL.
150158
* @remark Not implemented yet.

src/cpp/fastdds/xtypes/dynamic_types/DynamicTypeBuilderFactoryImpl.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include <fastdds/xtypes/type_representation/TypeObjectRegistry.hpp>
3232
#include <rtps/RTPSDomainImpl.hpp>
3333

34+
#include "idl_parser/IdlParser.hpp"
35+
3436
namespace eprosima {
3537
namespace fastdds {
3638
namespace dds {
@@ -72,6 +74,19 @@ traits<DynamicTypeBuilder>::ref_type DynamicTypeBuilderFactoryImpl::create_type_
7274
return nil;
7375
}
7476

77+
traits<DynamicTypeBuilder>::ref_type DynamicTypeBuilderFactoryImpl::create_type_w_idl(
78+
const std::string& idl) noexcept
79+
{
80+
using namespace idlparser;
81+
82+
traits<DynamicTypeBuilder>::ref_type ret_val;
83+
84+
Context context = Parser::instance()->parse_string(idl);
85+
ret_val = context.builder;
86+
87+
return ret_val;
88+
}
89+
7590
traits<DynamicTypeBuilder>::ref_type DynamicTypeBuilderFactoryImpl::create_type_w_type_object(
7691
const xtypes::TypeObject& type_object) noexcept
7792
{

src/cpp/fastdds/xtypes/dynamic_types/DynamicTypeBuilderFactoryImpl.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ class DynamicTypeBuilderFactoryImpl : public traits<DynamicTypeBuilderFactory>::
5454
const std::string& type_name,
5555
const IncludePathSeq& include_paths) noexcept override;
5656

57+
traits<DynamicTypeBuilder>::ref_type create_type_w_idl(
58+
const std::string& idl) noexcept override;
59+
5760
traits<DynamicTypeBuilder>::ref_type create_type_w_type_object(
5861
const xtypes::TypeObject& type_object) noexcept override;
5962

0 commit comments

Comments
 (0)