31namespace pegtl = tao::pegtl;
37 template<
int TableVal>
struct lookup_char {
38 using analyze_t = pegtl::analysis::generic<pegtl::analysis::rule_type::ANY>;
39 template<
typename Input>
static bool match(
Input&
in) {
44 in.bump_in_this_line(1);
60 struct nonblank_ch : pegtl::range<'!', '~'> {};
63 struct anyprint_ch : pegtl::ranges<' ', '~', '\t'> {};
67 struct comment : pegtl::if_must<pegtl::one<'#'>, pegtl::until<pegtl::eolf>>{};
68 struct whitespace : pegtl::plus<pegtl::sor<ws_char, comment>> {};
69 struct ws_or_eof : pegtl::sor<whitespace, pegtl::eof> {};
77 struct keyword : pegtl::sor<str_data, str_loop, str_global,
78 str_save, str_stop> {};
82 struct endq : pegtl::seq<Q, pegtl::at<pegtl::sor<
83 pegtl::one<' ','\n','\r','\t','#'>,
89 struct quoted_tail : pegtl::until<endq<Q>, pegtl::not_one<'\n'>> {};
91 struct quoted : pegtl::if_must<Q, quoted_tail<Q>> {};
92 struct singlequoted : quoted<pegtl::one<'\''>> {};
93 struct doublequoted : quoted<pegtl::one<'"'>> {};
94 struct field_sep : pegtl::seq<pegtl::bol, pegtl::one<';'>> {};
97 struct textfield : pegtl::if_must<field_sep, pegtl::until<field_sep>> {};
98 struct unquoted : pegtl::seq<pegtl::not_at<keyword>,
99 pegtl::not_at<pegtl::one<'_','$','#'>>,
100 pegtl::plus<nonblank_ch>> {};
105 struct datablockname : pegtl::star<nonblank_ch> {};
106 struct datablockheading : pegtl::sor<pegtl::seq<str_data, datablockname>, str_global> {};
107 struct tag : pegtl::seq<pegtl::one<'_'>, pegtl::plus<nonblank_ch>> {};
110 struct simunq : pegtl::seq<pegtl::plus<ordinary_char>, pegtl::at<ws_char>> {};
111 struct value : pegtl::sor<simunq, singlequoted, doublequoted,
112 textfield, unquoted> {};
113 struct item_tag : tag {};
114 struct item_value : value {};
115 struct loop_tag : tag {};
116 struct loop_value : value {};
117 struct loop_end : pegtl::opt<str_stop, ws_or_eof> {};
118 struct loop : pegtl::if_must<str_loop,
120 pegtl::plus<pegtl::seq<loop_tag, whitespace, pegtl::discard>>,
121 pegtl::sor<pegtl::plus<pegtl::seq<loop_value, ws_or_eof,
124 pegtl::at<pegtl::sor<keyword, pegtl::eof>>>,
126 struct missing_value : pegtl::bol {};
127 struct dataitem : pegtl::if_must<item_tag, whitespace,
128 pegtl::if_then_else<item_value, ws_or_eof,
131 struct framename : pegtl::plus<nonblank_ch> {};
132 struct endframe : str_save {};
133 struct frame : pegtl::if_must<str_save, framename, whitespace,
134 pegtl::star<pegtl::sor<dataitem, loop>>,
135 endframe, ws_or_eof> {};
136 struct datablock : pegtl::seq<datablockheading, ws_or_eof,
137 pegtl::star<pegtl::sor<dataitem, loop, frame>>> {};
138 struct content : pegtl::plus<datablock> {};
139 struct file : pegtl::seq<pegtl::opt<whitespace>,
140 pegtl::if_must<pegtl::not_at<pegtl::eof>,
141 content, pegtl::eof>> {};
142 struct one_block : pegtl::seq<pegtl::opt<whitespace>,
143 pegtl::if_must<pegtl::not_at<pegtl::eof>, datablock>> {};
152 static const std::string s =
"parse error";
155#define error_msg(rule, msg) \
156 template<> inline const std::string& error_message<rule>() { \
157 static const std::string s = msg; \
160error_msg(rules::quoted_tail<pegtl::one<
'\''>>,
"unterminated 'string'")
161error_msg(rules::quoted_tail<pegtl::one<'"'>>, "unterminated \"
string\"")
162error_msg(pegtl::until<rules::field_sep>, "unterminated text field")
163error_msg(rules::framename, "unnamed save_ frame")
164error_msg(rules::content, "expected block header (data_)")
167template<
typename Rule>
struct Errors :
public pegtl::normal<Rule> {
168 template<
typename Input,
typename ... States>
169 static void raise(
const Input& in, States&& ...) {
170 throw pegtl::parse_error(error_message<Rule>()
178template<
typename Rule>
struct Action : pegtl::nothing<Rule> {};
192template<>
struct Action<rules::datablockname> {
193 template<
typename Input>
static void apply(
const Input& in, Document& out) {
194 out.blocks.emplace_back(in.string());
195 Block& block = out.blocks.back();
198 if (block.name.empty())
200 out.items_ = &block.items;
203template<>
struct Action<rules::str_global> {
204 template<
typename Input>
static void apply(
const Input&, Document& out) {
205 out.blocks.emplace_back();
206 out.items_ = &out.blocks.back().items;
209template<>
struct Action<rules::framename> {
210 template<
typename Input>
static void apply(
const Input& in, Document& out) {
211 out.items_->emplace_back(FrameArg{in.string()});
212 out.items_->back().line_number = in.iterator().line;
213 out.items_ = &out.items_->back().frame.items;
216template<>
struct Action<rules::endframe> {
217 template<
typename Input>
static void apply(
const Input&, Document& out) {
218 out.items_ = &out.blocks.back().items;
221template<>
struct Action<rules::item_tag> {
222 template<
typename Input>
static void apply(
const Input& in, Document& out) {
223 out.items_->emplace_back(in.string());
224 out.items_->back().line_number = in.iterator().line;
227template<>
struct Action<rules::item_value> {
228 template<
typename Input>
static void apply(
const Input& in, Document& out) {
229 Item& last_item = out.items_->back();
231 last_item.pair[1] = in.string();
234template<>
struct Action<rules::str_loop> {
235 template<
typename Input>
static void apply(
const Input& in, Document& out) {
236 out.items_->emplace_back(LoopArg{});
237 out.items_->back().line_number = in.iterator().line;
240template<>
struct Action<rules::loop_tag> {
241 template<
typename Input>
static void apply(
const Input& in, Document& out) {
242 Item& last_item = out.items_->back();
244 last_item.loop.tags.emplace_back(in.string());
247template<>
struct Action<rules::loop_value> {
248 template<
typename Input>
static void apply(
const Input& in, Document& out) {
249 Item& last_item = out.items_->back();
251 last_item.loop.values.emplace_back(in.string());
254template<>
struct Action<rules::loop> {
255 template<
typename Input>
static void apply(
const Input& in, Document& out) {
256 Item& last_item = out.items_->back();
258 const Loop& loop = last_item.loop;
259 if (loop.values.size() % loop.tags.size() != 0)
260 throw pegtl::parse_error(
261 "Wrong number of values in loop " + loop.common_prefix() +
"*",
268 pegtl::parse<rules::file, Action, Errors>(
in,
d);
273 doc.source =
in.source();
280 if (block.name ==
" ")
281 fail(
doc.source +
": missing block name (bare data_)");
289template<
typename Input>
291 pegtl::parse<rules::one_block, Action, Errors>(
in,
d);
298#define GEMMI_CIF_FILE_INPUT(in, path) \
299 tao::pegtl::read_input<> in(gemmi::file_open(path.c_str(), "rb").release(), path)
301#define GEMMI_CIF_FILE_INPUT(in, path) \
302 tao::pegtl::file_input<> in(path)
311 pegtl::memory_input<>
in(data, size, name);
316 pegtl::cstream_input<>
in(f,
bufsize, name);
327template<
typename Rule>
struct CheckAction : pegtl::nothing<Rule> {};
329template<>
struct CheckAction<rules::missing_value> {
330 template<
typename Input>
static void apply(
const Input& in) {
331 throw pegtl::parse_error(
"tag without value", in);
337 return pegtl::parse<rules::file, CheckAction, Errors>(
in);
338 }
catch (pegtl::parse_error&
e) {
351 if (
input.is_stdin())
359 pegtl::memory_input<>
in(
mem.data(),
mem.size(),
input.path());
368 if (
input.is_compressed()) {
371 input.path().c_str()));
373 if (
input.is_stdin())