Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,20 @@ add_library(
src/networkprotocoldsl/parser/grammar/identifier.cpp
src/networkprotocoldsl/parser/grammar/literals.hpp
src/networkprotocoldsl/parser/grammar/literals.cpp
src/networkprotocoldsl/parser/grammar/message.hpp
src/networkprotocoldsl/parser/grammar/message.cpp
src/networkprotocoldsl/parser/grammar/messagedata.hpp
src/networkprotocoldsl/parser/grammar/messagedata.cpp
src/networkprotocoldsl/parser/grammar/messagesequence.hpp
src/networkprotocoldsl/parser/grammar/messagesequence.cpp
src/networkprotocoldsl/parser/grammar/tokenparts.hpp
src/networkprotocoldsl/parser/grammar/tokenparts.cpp
src/networkprotocoldsl/parser/grammar/traits.hpp
src/networkprotocoldsl/parser/grammar/traits.cpp
src/networkprotocoldsl/parser/grammar/typeparameter.hpp
src/networkprotocoldsl/parser/grammar/typeparameter.cpp
src/networkprotocoldsl/parser/parse.hpp
src/networkprotocoldsl/parser/parse.cpp
src/networkprotocoldsl/parser/support/recursiveparser.cpp
src/networkprotocoldsl/parser/support/recursiveparser.hpp
src/networkprotocoldsl/parser/tree/booleanliteral.cpp
Expand Down
34 changes: 17 additions & 17 deletions notes/source-code-http-client-server.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
message HTTP Request {
message "HTTP Request" {
when: Open;
then: AwaitResponse;
agent: Client;
Expand Down Expand Up @@ -28,24 +28,24 @@ message “HTTP Request” {
}
parts {
tokens { verb }
terminator { “ “ }
terminator { " " }
tokens { request_target }
terminator { “ “ }
terminator { " " }
tokens {
HTTP/”, major_version, “.”, minor_version
"HTTP/" major_version "." minor_version
}
terminator { \r\n }
terminator { "\r\n" }
for header in headers {
tokens { header.key }
terminator { “:” }
terminator { ":" }
tokens { header.value }
terminator { \r\n}
terminator { "\r\n"}
}
terminator { \r\n }
terminator { "\r\n" }
}
}

message HTTP Response {
message "HTTP Response" {
when: AwaitResponse;
then: Open;
agent: server;
Expand Down Expand Up @@ -75,24 +75,24 @@ message “HTTP Response” {
}
parts {
tokens {
HTTP/, major_version, “.”, minor_version
"HTTP/", major_version, ".", minor_version
}
terminator { “ “ }
terminator { " " }
tokens { response_code }
terminator { “ “ }
terminator { " " }
tokens { reason_phrase }
terminator { \r\n }
terminator { "\r\n" }
for header in headers {
tokens { header.key }
terminator { “:” }
terminator { ":" }
tokens { header.value }
terminator { \r\n}
terminator { "\r\n"}
}
terminator { \r\n }
terminator { "\r\n" }
}
}

message Client Closes Connection {
message "Client Closes Connection" {
when: Open;
then: Closed;
agent: Client;
Expand Down
1 change: 1 addition & 0 deletions src/networkprotocoldsl/parser/grammar/message.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <networkprotocoldsl/parser/grammar/message.hpp>
133 changes: 133 additions & 0 deletions src/networkprotocoldsl/parser/grammar/message.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#ifndef INCLUDED_NETWORKPROTOCOLDSL_GRAMMAR_MESSAGE_HPP
#define INCLUDED_NETWORKPROTOCOLDSL_GRAMMAR_MESSAGE_HPP

#include <memory>
#include <optional>
#include <vector>

#include <networkprotocoldsl/lexer/token.hpp>
#include <networkprotocoldsl/parser/grammar/messagedata.hpp>
#include <networkprotocoldsl/parser/grammar/messagesequence.hpp>
#include <networkprotocoldsl/parser/grammar/traits.hpp>
#include <networkprotocoldsl/parser/support/recursiveparser.hpp>
#include <networkprotocoldsl/parser/tree/message.hpp>

namespace networkprotocoldsl::parser::grammar {

class Message
: public support::RecursiveParser<Message, ParseTraits, Tracer<Message>> {
public:
static constexpr const char *name = "Message";
static void partial_match() {}
static StringLiteral *recurse_one(lexer::token::keyword::Message) {
return nullptr;
}
static void partial_match(lexer::token::keyword::Message,
std::shared_ptr<const tree::StringLiteral>) {}
static MessageDataPair *
recurse_many(lexer::token::keyword::Message,
std::shared_ptr<const tree::StringLiteral>,
lexer::token::punctuation::CurlyBraceOpen) {
return nullptr;
}
static MessageData *
recurse_maybe(lexer::token::keyword::Message,
std::shared_ptr<const tree::StringLiteral>,
lexer::token::punctuation::CurlyBraceOpen,
std::vector<std::shared_ptr<const tree::MessageDataPair>>) {
return nullptr;
}
static void
partial_match(lexer::token::keyword::Message,
std::shared_ptr<const tree::StringLiteral>,
lexer::token::punctuation::CurlyBraceOpen,
std::vector<std::shared_ptr<const tree::MessageDataPair>>,
std::nullopt_t) {}

static ParseStateReturn
match(TokenIterator begin, TokenIterator end, lexer::token::keyword::Message,
std::shared_ptr<const tree::StringLiteral> messagename,
lexer::token::punctuation::CurlyBraceOpen,
std::vector<std::shared_ptr<const tree::MessageDataPair>> attributes,
std::nullopt_t, lexer::token::punctuation::CurlyBraceClose) {
auto message = std::make_shared<tree::Message>();
message->name = messagename;
message->data = std::make_shared<const tree::MessageData>();
message->parts = std::make_shared<const tree::MessageSequence>();
bool seen_when = false;
bool seen_then = false;
bool seen_agent = false;
for (auto &attr : attributes) {
if (attr->first == "when") {
message->when = attr->second->name;
seen_when = true;
} else if (attr->first == "then") {
message->then = attr->second->name;
seen_then = true;
} else if (attr->first == "agent") {
message->agent = attr->second->name;
seen_agent = true;
}
}
if (!(seen_when && seen_then && seen_agent)) {
return {std::nullopt, begin, end};
} else {
return {std::const_pointer_cast<const tree::Message>(message), begin,
end};
}
}

static MessageParts *
recurse_one(lexer::token::keyword::Message,
std::shared_ptr<const tree::StringLiteral>,
lexer::token::punctuation::CurlyBraceOpen,
std::vector<std::shared_ptr<const tree::MessageDataPair>>,
std::shared_ptr<const tree::MessageData>) {
return nullptr;
}
static void
partial_match(lexer::token::keyword::Message,
std::shared_ptr<const tree::StringLiteral>,
lexer::token::punctuation::CurlyBraceOpen,
std::vector<std::shared_ptr<const tree::MessageDataPair>>,
std::shared_ptr<const tree::MessageData>,
std::shared_ptr<const tree::MessageSequence>) {}
static ParseStateReturn
match(TokenIterator begin, TokenIterator end, lexer::token::keyword::Message,
std::shared_ptr<const tree::StringLiteral> messagename,
lexer::token::punctuation::CurlyBraceOpen,
std::vector<std::shared_ptr<const tree::MessageDataPair>> attributes,
std::shared_ptr<const tree::MessageData> data,
std::shared_ptr<const tree::MessageSequence> sequence,
lexer::token::punctuation::CurlyBraceClose) {
auto message = std::make_shared<tree::Message>();
message->name = messagename;
message->data = data;
message->parts = sequence;
bool seen_when = false;
bool seen_then = false;
bool seen_agent = false;
for (auto &attr : attributes) {
if (attr->first == "when") {
message->when = attr->second->name;
seen_when = true;
} else if (attr->first == "then") {
message->then = attr->second->name;
seen_then = true;
} else if (attr->first == "agent") {
message->agent = attr->second->name;
seen_agent = true;
}
}
if (!(seen_when && seen_then && seen_agent)) {
return {std::nullopt, begin, end};
} else {
return {std::const_pointer_cast<const tree::Message>(message), begin,
end};
}
};
};

} // namespace networkprotocoldsl::parser::grammar

#endif
1 change: 1 addition & 0 deletions src/networkprotocoldsl/parser/grammar/messagesequence.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <networkprotocoldsl/parser/grammar/messagesequence.hpp>
118 changes: 118 additions & 0 deletions src/networkprotocoldsl/parser/grammar/messagesequence.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#ifndef INCLUDED_NETWORKPROTOCOLDSL_PARSER_GRAMMAR_MESSAGEFORLOOP_HPP
#define INCLUDED_NETWORKPROTOCOLDSL_PARSER_GRAMMAR_MESSAGEFORLOOP_HPP

#include <memory>
#include <vector>

#include <networkprotocoldsl/lexer/token.hpp>
#include <networkprotocoldsl/parser/grammar/identifier.hpp>
#include <networkprotocoldsl/parser/grammar/tokenparts.hpp>
#include <networkprotocoldsl/parser/grammar/traits.hpp>
#include <networkprotocoldsl/parser/support/recursiveparser.hpp>
#include <networkprotocoldsl/parser/tree/messageforloop.hpp>

namespace networkprotocoldsl::parser::grammar {

class MessageSequence; // Forward declaration

class MessageForLoop
: public support::RecursiveParser<MessageForLoop, ParseTraits,
Tracer<MessageForLoop>> {
public:
static constexpr const char *name = "MessageForLoop";
static void partial_match() {}
static IdentifierReference *recurse_one(lexer::token::keyword::For) {
return nullptr;
}
static void partial_match(lexer::token::keyword::For,
std::shared_ptr<const tree::IdentifierReference>) {}
static IdentifierReference *
recurse_one(lexer::token::keyword::For,
std::shared_ptr<const tree::IdentifierReference>,
lexer::token::keyword::In) {
return nullptr;
}
static void partial_match(lexer::token::keyword::For,
std::shared_ptr<const tree::IdentifierReference>,
lexer::token::keyword::In,
std::shared_ptr<const tree::IdentifierReference>) {}
static MessageSequence *
recurse_one(lexer::token::keyword::For,
std::shared_ptr<const tree::IdentifierReference>,
lexer::token::keyword::In,
std::shared_ptr<const tree::IdentifierReference>,
lexer::token::punctuation::CurlyBraceOpen) {
return nullptr;
}
static void partial_match(lexer::token::keyword::For,
std::shared_ptr<const tree::IdentifierReference>,
lexer::token::keyword::In,
std::shared_ptr<const tree::IdentifierReference>,
lexer::token::punctuation::CurlyBraceOpen,
std::shared_ptr<const tree::MessageSequence>) {}
static ParseStateReturn
match(TokenIterator begin, TokenIterator end, lexer::token::keyword::For,
std::shared_ptr<const tree::IdentifierReference> identifier1,
lexer::token::keyword::In,
std::shared_ptr<const tree::IdentifierReference> identifier2,
lexer::token::punctuation::CurlyBraceOpen,
std::shared_ptr<const tree::MessageSequence> seq,
lexer::token::punctuation::CurlyBraceClose) {
return {std::make_shared<const tree::MessageForLoop>(identifier1,
identifier2, seq),
begin, end};
}
};

class MessagePart : public support::RecursiveParser<MessagePart, ParseTraits,
Tracer<MessagePart>> {
public:
static constexpr const char *name = "MessagePart";
static std::tuple<TokenSequence, Terminator, MessageForLoop> *recurse_any() {
return nullptr;
}
static ParseStateReturn match(TokenIterator begin, TokenIterator end,
tree::MessagePart part) {
return {std::make_shared<const tree::MessagePart>(part), begin, end};
}
};

class MessageSequence
: public support::RecursiveParser<MessageSequence, ParseTraits,
Tracer<MessageSequence>> {
public:
static constexpr const char *name = "MessageSequence";
static MessagePart *recurse_many() { return nullptr; }
static ParseStateReturn
match(TokenIterator begin, TokenIterator end,
std::vector<std::shared_ptr<const tree::MessagePart>> parts) {
return {std::make_shared<const tree::MessageSequence>(parts), begin, end};
}
};

class MessageParts : public support::RecursiveParser<MessageParts, ParseTraits,
Tracer<MessageParts>> {
public:
static constexpr const char *name = "MesageParts";
static void partial_match() {}
static void partial_match(lexer::token::keyword::Parts) {}
static MessageSequence *
recurse_one(lexer::token::keyword::Parts,
lexer::token::punctuation::CurlyBraceOpen) {
return nullptr;
}
static void partial_match(lexer::token::keyword::Parts,
lexer::token::punctuation::CurlyBraceOpen,
std::shared_ptr<const tree::MessageSequence>) {}
static ParseStateReturn
match(TokenIterator begin, TokenIterator end, lexer::token::keyword::Parts,
lexer::token::punctuation::CurlyBraceOpen,
std::shared_ptr<const tree::MessageSequence> parts,
lexer::token::punctuation::CurlyBraceClose) {
return {parts, begin, end};
}
};

} // namespace networkprotocoldsl::parser::grammar

#endif // INCLUDED_NETWORKPROTOCOLDSL_PARSER_GRAMMAR_MESSAGEFORLOOP_HPP
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <networkprotocoldsl/parser/grammar/protocoldescription.hpp>
37 changes: 37 additions & 0 deletions src/networkprotocoldsl/parser/grammar/protocoldescription.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef INCLUDED_NETWORKPROTOCOLDSL_PARSER_GRAMMAR_PROTOCOLDESCRIPTION_HPP
#define INCLUDED_NETWORKPROTOCOLDSL_PARSER_GRAMMAR_PROTOCOLDESCRIPTION_HPP

#include <memory>
#include <optional>
#include <vector>

#include <networkprotocoldsl/parser/grammar/message.hpp>
#include <networkprotocoldsl/parser/grammar/traits.hpp>
#include <networkprotocoldsl/parser/support/recursiveparser.hpp>

#include <networkprotocoldsl/parser/tree/protocoldescription.hpp>

namespace networkprotocoldsl::parser::grammar {

class ProtocolDescription
: public support::RecursiveParser<ProtocolDescription, ParseTraits,
Tracer<ProtocolDescription>> {
public:
static constexpr const char *name = "ProtocolDescription";
static Message *recurse_many() { return nullptr; };
static ParseStateReturn
match(TokenIterator begin, TokenIterator end,
std::vector<std::shared_ptr<const tree::Message>> messages) {
auto protocol_description = std::make_shared<tree::ProtocolDescription>();
for (auto &message : messages) {
protocol_description->emplace(message->name->value, message);
}
return {std::const_pointer_cast<const tree::ProtocolDescription>(
protocol_description),
begin, end};
};
};

} // namespace networkprotocoldsl::parser::grammar

#endif
Loading
Loading