📄 parselets.h
字号:
std::ptrdiff_t d = m_p.parse(test_it, end); if(d == -1) break; rd += d; it = test_it; m_result.push_back(m_p.m_result); } return rd; }};template<class P>star_p<P> make_star(const P& p) { return star_p<P>(p);}// Parses: FirstType | SecondType | ThirdTypetemplate<class FirstType, class SecondType, class ThirdType>class or_trio_p : public parselet { public: typedef FirstType first_type; typedef SecondType second_type; typedef ThirdType third_type; typedef or_trio_p<FirstType, SecondType, ThirdType> self_type; typedef typename FirstType::result_type first_result_type; typedef typename SecondType::result_type second_result_type; typedef typename ThirdType::result_type third_result_type; typedef struct { std::pair<bool, first_result_type> first; std::pair<bool, second_result_type> second; std::pair<bool, third_result_type> third; } result_type; result_type m_result; first_type m_first; second_type m_second; third_type m_third; or_trio_p(const first_type& first, const second_type& second, const third_type& third) : m_first(first), m_second(second), m_third(third) {} std::ptrdiff_t parse(const_iterator& it, const const_iterator& end) { const_iterator ita[3] = {it, it, it}; std::ptrdiff_t d[3] = { m_first.parse(ita[0], end), m_second.parse(ita[1], end), m_third.parse(ita[2], end)}; std::ptrdiff_t dmax = -1; for(int i=0;i<3;i++) { if(d[i] != -1 && (dmax == -1 || d[i] > dmax)) { dmax = d[i]; } } if(dmax == -1) return -1; if(d[0] == dmax) { it = ita[0]; m_result.first = std::make_pair(true, m_first.m_result); m_result.second = std::make_pair(false, m_second.m_result); m_result.third = std::make_pair(false, m_third.m_result); } else if(d[1] == dmax) { it = ita[1]; m_result.first = std::make_pair(false, m_first.m_result); m_result.second = std::make_pair(true, m_second.m_result); m_result.third = std::make_pair(false, m_third.m_result); } else if(d[2] == dmax) { it = ita[2]; m_result.first = std::make_pair(false, m_first.m_result); m_result.second = std::make_pair(false, m_second.m_result); m_result.third = std::make_pair(true, m_third.m_result); } else { m_result.first = std::make_pair(false, m_first.m_result); m_result.second = std::make_pair(false, m_second.m_result); m_result.third = std::make_pair(false, m_third.m_result); } return dmax; } bool matched_first() const { return m_result.first.first;} bool matched_second() const { return m_result.second.first;} bool matched_third() const { return m_result.third.first;} first_result_type get_first_result() const { return m_result.first.second;} second_result_type get_second_result() const { return m_result.second.second;} third_result_type get_third_result() const { return m_result.third.second;}};// let the compiler deduce the type from the argstemplate<class T1, class T2, class T3>or_trio_p<T1, T2, T3> make_or_trio_p(const T1& t1, const T2& t2, const T3& t3) { return or_trio_p<T1, T2, T3>(t1, t2, t3);}////////////////////////////////// Composite parselets// More as a pattern than for real useclass list_p : public parselet { public: typedef list_p self_type; typedef std::list<parselet*> result_type; result_type m_result; ~list_p(); void push_back(parselet* p) { m_result.push_back(p);} std::ptrdiff_t parse(const_iterator& it, const const_iterator& end);};class options_p : public parselet { public: std::list<parselet*> m_options; typedef parselet* result_type; result_type m_result; ~options_p(); void push_back(parselet* p) { m_options.push_back(p);} std::ptrdiff_t parse(const_iterator& it, const const_iterator& end);};////////////////////////////////// Number parser// Parses any decimal number not using scientific notation// includes: (+|-)?d+(.d*)? | .d+class number_p : public parselet { public: typedef number_p self_type; typedef double result_type; result_type m_result; std::ptrdiff_t parse(const_iterator& it, const const_iterator& end); result_type get_result() const { return m_result;}};// Parses a list of numbers// The list is sepatated with white space// The parser stops to the first not number sequence or at endclass number_list_p : public parselet { public: typedef number_list_p self_type; typedef std::vector<double> result_type; result_type m_result; std::ptrdiff_t parse(const_iterator& it, const const_iterator& endit); // result related helpers const result_type& get_result() const { return m_result;} size_t size() const {return m_result.size();} result_type::iterator begin() {return m_result.begin();} result_type::iterator end() {return m_result.end();} result_type::const_iterator begin() const {return m_result.begin();} result_type::const_iterator end() const {return m_result.end();}};////////////////////////////////// Domain parselets// the following teplates must be extended // to use std::isalpha and std::isdigit// NameStartChar ::= (Letter | '_' | ':') template <class CharType>struct xml_name_start_ch { bool operator()(CharType ch) { return isalpha(ch) || ch == '_' || ch == ':'; }};template <class CharType>struct xml_ncname_start_ch { bool operator()(CharType ch) { return xml_name_start_ch<CharType>()(ch) && ch != ':'; }};// NameChar ::= Letter | Digit | '.' | '-' | '_' | ':'template <class CharType>struct xml_name_ch { bool operator()(CharType ch) { return isalpha(ch) || isdigit(ch) || ch == '.' || ch == '-' || ch == '_' || ch == ':'; }};template <class CharType>struct xml_ncname_ch { bool operator()(char ch) { return xml_name_ch<CharType>()(ch) && ch != ':'; }};// Space ::= #x20 | #x9 | #xD | #xAtemplate <class CharType>struct xml_space_ch { bool operator()(CharType ch) { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; }};typedef name_p< char, xml_name_start_ch<char>, xml_name_ch<char> > xml_name_p;typedef name_p< char, xml_ncname_start_ch<char>, xml_ncname_ch<char> > xml_ncname_p;typedef name_p< char, xml_name_ch<char>, xml_name_ch<char> > xml_nmtoken_p;// time_unit ::= "h" | "min" | "s" | "ms"class time_unit_p : public parselet { public: typedef time_unit_p self_type; typedef enum {tu_h, tu_min, tu_s, tu_ms} result_type; result_type m_result; std::ptrdiff_t parse(const_iterator& it, const const_iterator& end);};// length_unit ::= "px" | "%"class length_unit_p : public parselet { public: typedef length_unit_p self_type; typedef enum {px, percent} result_type; result_type m_result; std::ptrdiff_t parse(const_iterator& it, const const_iterator& end);};class full_clock_value_p : public parselet { public: typedef full_clock_value_p self_type; typedef struct { int hours; int minutes; int seconds; int fraction; } result_type; result_type m_result; std::ptrdiff_t parse(const_iterator& it, const const_iterator& end);};class partial_clock_value_p : public parselet { public: typedef partial_clock_value_p self_type; typedef struct { int minutes; int seconds; int fraction; } result_type; result_type m_result; std::ptrdiff_t parse(const_iterator& it, const const_iterator& end);};class timecount_value_p : public parselet { public: typedef full_clock_value_p self_type; typedef struct { number_p::result_type value; time_unit_p::result_type unit; } result_type; result_type m_result; std::ptrdiff_t parse(const_iterator& it, const const_iterator& end);};typedef or_trio_p<full_clock_value_p, partial_clock_value_p, timecount_value_p> clock_value_sel_p; const int S_MS = 1000;const int MIN_MS = 60*S_MS;const int H_MS = 60*MIN_MS;// Though clock_value_sel_p does the job of parsing a clock value// implement a handy class that will convert any matching clock alt to ms.class clock_value_p : public parselet { public: typedef clock_value_p self_type; typedef long result_type; result_type m_result; std::ptrdiff_t parse(const_iterator& it, const const_iterator& end); // This will return a valid value when the previous call // to parse returned a value != -1. result_type get_value() const { return m_result;}};// offset-value ::= (( S? "+" | "-" S? )? ( Clock-value )class offset_value_p : public parselet { public: typedef clock_value_p self_type; typedef long result_type; result_type m_result; std::ptrdiff_t parse(const_iterator& it, const const_iterator& end); result_type get_value() const { return m_result;}};class coord_p : public parselet { public: typedef coord_p self_type; typedef struct { number_p::result_type value; length_unit_p::result_type unit; } result_type; result_type m_result; std::ptrdiff_t parse(const_iterator& it, const const_iterator& end); length_unit_p::result_type get_units() const { return m_result.unit;} int get_px() const { return int(floor(m_result.value+0.5));} double get_percent() const { return std::max<double>(0.0, std::min<double>(100.0, m_result.value)); }};// region_dim ::= S? (int|dec) ((px)? | %)class region_dim_p : public parselet { public: typedef coord_p self_type; typedef struct { int int_val; double dbl_val; bool relative; } result_type; result_type m_result; std::ptrdiff_t parse(const_iterator& it, const const_iterator& end); int get_px_val() const { return m_result.int_val;} double get_relative_val() const { return m_result.dbl_val;} bool is_relative() const { return m_result.relative;}};// point_p ::= S? (? d+ S? , S? d+ S? )?class point_p : public parselet { public: typedef coord_p self_type; typedef struct { int_p::result_type x; int_p::result_type y; } result_type; result_type m_result; std::ptrdiff_t parse(const_iterator& it, const const_iterator& end); int get_x() const { return m_result.x;} int get_y() const { return m_result.y;}};//parses smtpe=d+:d+:d+[:d+.d+]class smpte_p : public parselet { public: std::ptrdiff_t parse(const_iterator& it, const const_iterator& end); long int get_time(); //returns the parsed time converted to ms. int m_result[5]; int m_frame_rate; bool m_drop;};class npt_p : public parselet { public: std::ptrdiff_t parse(const_iterator& it, const const_iterator& end); long int get_time(); //returns the parsed time converted to ms. long int m_result; int m_frame_rate; bool m_drop;};class mediaclipping_p : public parselet { public: std::ptrdiff_t parse(const_iterator& it, const const_iterator& end); long int get_time(); //returns the parsed time converted to ms. long int m_result; int m_frame_rate; bool m_drop;};} // namespace lib } // namespace ambulant#endif // AMBULANT_LIB_PARSELETS_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -