Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
59b221cb
Commit
59b221cb
authored
May 26, 2018
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add fsm_transition utility to DSL for FSM
parent
d4cf1f7a
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
61 additions
and
15 deletions
+61
-15
libcaf_core/caf/detail/parser/fsm.hpp
libcaf_core/caf/detail/parser/fsm.hpp
+45
-0
libcaf_core/caf/detail/parser/read_ini.hpp
libcaf_core/caf/detail/parser/read_ini.hpp
+8
-11
libcaf_core/test/read_ini.cpp
libcaf_core/test/read_ini.cpp
+8
-4
No files found.
libcaf_core/caf/detail/parser/fsm.hpp
View file @
59b221cb
...
...
@@ -20,6 +20,8 @@
#include <cstring>
#include "caf/detail/pp.hpp"
namespace
caf
{
namespace
detail
{
...
...
@@ -59,15 +61,18 @@ extern const char octal_chars[9];
ps.code = mismatch_ec; \
return;
/// Starts the definition of an FSM.
#define start() \
char ch = ps.current(); \
goto s_init; \
s_unexpected_eof: \
__attribute__((unused)); \
ps.code = ec::unexpected_eof; \
return; \
{ \
static constexpr ec mismatch_ec = ec::unexpected_character
/// Defines a non-terminal state in the FSM.
#define state(name) \
CAF_FSM_EVAL_MISMATCH_EC \
} \
...
...
@@ -78,6 +83,7 @@ extern const char octal_chars[9];
goto s_unexpected_eof; \
e_##name : __attribute__((unused));
/// Defines a terminal state in the FSM.
#define term_state(name) \
CAF_FSM_EVAL_MISMATCH_EC \
} \
...
...
@@ -88,6 +94,7 @@ extern const char octal_chars[9];
goto s_fin; \
e_##name : __attribute__((unused));
/// Ends the definition of an FSM.
#define fin() \
CAF_FSM_EVAL_MISMATCH_EC \
} \
...
...
@@ -171,6 +178,44 @@ extern const char octal_chars[9];
epsilon(__VA_ARGS__) \
}
#define CAF_FSM_TRANSITION_IMPL2(fsm_call, target) \
ps.next(); \
fsm_call; \
if (ps.code > ec::trailing_character) \
return; \
ch = ps.current(); \
goto s_##target;
#define CAF_FSM_TRANSITION_IMPL3(fsm_call, target, whitelist) \
if (::caf::detail::in_whitelist(whitelist, ch)) { \
CAF_FSM_TRANSITION_IMPL2(fsm_call, target) \
}
#define CAF_FSM_TRANSITION_IMPL4(fsm_call, target, whitelist, action) \
if (::caf::detail::in_whitelist(whitelist, ch)) { \
action; \
CAF_FSM_TRANSITION_IMPL2(fsm_call, target) \
}
#define CAF_FSM_TRANSITION_IMPL5(fsm_call, target, whitelist, action, \
error_code) \
if (::caf::detail::in_whitelist(whitelist, ch)) { \
if (!action) { \
ps.code = error_code; \
return; \
} \
CAF_FSM_TRANSITION_IMPL2(fsm_call, target) \
}
/// Makes an transition transition into another FSM, resuming at state `target`.
#define fsm_transition(...) \
CAF_PP_OVERLOAD(CAF_FSM_TRANSITION_IMPL, __VA_ARGS__)(__VA_ARGS__)
#define fsm_transition_if(statement, ...) \
if (statement) { \
fsm_transition(__VA_ARGS__) \
}
#define CAF_FSM_EPSILON_IMPL2(fsm_call, target) \
fsm_call; \
if (ps.code > ec::trailing_character) \
...
...
libcaf_core/caf/detail/parser/read_ini.hpp
View file @
59b221cb
...
...
@@ -54,12 +54,9 @@ namespace parser {
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
void
read_ini_comment
(
state
<
Iterator
,
Sentinel
>&
ps
,
Consumer
&
)
{
start
();
state
(
init
)
{
transition
(
await_newline
,
';'
)
}
term_state
(
await_newline
)
{
term_state
(
init
)
{
transition
(
done
,
'\n'
)
transition
(
await_newline
)
transition
(
init
)
}
term_state
(
done
)
{
// nop
...
...
@@ -71,10 +68,10 @@ template <class Iterator, class Sentinel, class Consumer>
void
read_ini_value
(
state
<
Iterator
,
Sentinel
>&
ps
,
Consumer
&
consumer
);
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
void
read_ini_list
(
state
<
Iterator
,
Sentinel
>&
ps
,
Consumer
&
consumer
)
{
void
read_ini_list
(
state
<
Iterator
,
Sentinel
>&
ps
,
Consumer
&
&
consumer
)
{
start
();
state
(
init
)
{
transition
(
before_value
,
'['
,
consumer
.
begin_list
()
)
epsilon
(
before_value
)
}
state
(
before_value
)
{
transition
(
before_value
,
"
\t\n
"
)
...
...
@@ -95,14 +92,14 @@ void read_ini_list(state<Iterator, Sentinel>& ps, Consumer& consumer) {
}
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
void
read_ini_map
(
state
<
Iterator
,
Sentinel
>&
ps
,
Consumer
&
consumer
)
{
void
read_ini_map
(
state
<
Iterator
,
Sentinel
>&
ps
,
Consumer
&
&
consumer
)
{
std
::
string
key
;
auto
alnum_or_dash
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'-'
||
x
==
'_'
;
};
start
();
state
(
init
)
{
transition
(
await_key_name
,
'{'
,
consumer
.
begin_map
()
)
epsilon
(
await_key_name
)
}
state
(
await_key_name
)
{
transition
(
await_key_name
,
"
\t\n
"
)
...
...
@@ -147,8 +144,8 @@ void read_ini_value(state<Iterator, Sentinel>& ps, Consumer& consumer) {
fsm_epsilon
(
read_number
(
ps
,
consumer
),
done
,
'.'
)
fsm_epsilon
(
read_bool
(
ps
,
consumer
),
done
,
"ft"
)
fsm_epsilon
(
read_number_or_timespan
(
ps
,
consumer
),
done
,
decimal_chars
)
fsm_
epsilon
(
read_ini_list
(
ps
,
consumer
),
done
,
'['
)
fsm_
epsilon
(
read_ini_map
(
ps
,
consumer
),
done
,
'{'
)
fsm_
transition
(
read_ini_list
(
ps
,
consumer
.
begin_list
()
),
done
,
'['
)
fsm_
transition
(
read_ini_map
(
ps
,
consumer
.
begin_map
()
),
done
,
'{'
)
}
term_state
(
done
)
{
// nop
...
...
libcaf_core/test/read_ini.cpp
View file @
59b221cb
...
...
@@ -35,20 +35,24 @@ using log_type = std::vector<std::string>;
struct
test_consumer
{
log_type
log
;
void
begin_map
()
{
test_consumer
&
begin_map
()
{
log
.
emplace_back
(
"{"
);
return
*
this
;
}
void
end_map
()
{
test_consumer
&
end_map
()
{
log
.
emplace_back
(
"}"
);
return
*
this
;
}
void
begin_list
()
{
test_consumer
&
begin_list
()
{
log
.
emplace_back
(
"["
);
return
*
this
;
}
void
end_list
()
{
test_consumer
&
end_list
()
{
log
.
emplace_back
(
"]"
);
return
*
this
;
}
void
key
(
std
::
string
name
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment