glslが何であるかを私たちがどのように知っているかはまだわかりません。したがって、実際の入力形式については、大まかな推測しかできません。
私がこれを私が適切だと思う最も簡単な方法で解釈するとしましょう(ばかばかしいほど役に立たないことはありません):
annot = "@bind" >> ident >> eol;
declaration =
omit [ +(ident >> !char_(';')) ] // omit the type, TODO
>> ident >> ';' >> eol;
これで、必要なのは、注釈を含む行が見つかるまで完全な行を無視する簡単な方法です。
ignore = !annot >> *(char_ - eol) >> eol;
@bind
宣言が続かない行を無視したい場合は、!combi
の代わりに使用することをお勧めします!annot
。
これはあなたにとって単なるスターターです。また、無視できる線のこのすべての「暗黙の」定義が多くのバックトラックを引き起こす可能性があるというわけではありません。したがって、一流のパフォーマンスを期待しないでください。
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted.hpp>
#include <map>
namespace qi = boost::spirit::qi;
typedef std::map<std::string, std::string> Map;
template <typename It>
struct grammar : qi::grammar<It, Map(), qi::blank_type>
{
grammar() : grammar::base_type(start)
{
using namespace qi;
ident = lexeme [ alpha >> *alnum ];
annot = "@bind" >> ident >> eol;
declaration =
omit [ +(ident >> !char_(';')) ] // omit the type, TODO
>> ident >> ';' >> eol;
ignore = !annot >> *(char_ - eol) >> eol;
combi = annot >> declaration;
start = *ignore >> combi % *ignore;
BOOST_SPIRIT_DEBUG_NODE(start);
BOOST_SPIRIT_DEBUG_NODE(combi);
BOOST_SPIRIT_DEBUG_NODE(ignore);
BOOST_SPIRIT_DEBUG_NODE(declaration);
BOOST_SPIRIT_DEBUG_NODE(annot);
BOOST_SPIRIT_DEBUG_NODE(ident);
}
private:
qi::rule<It, qi::blank_type> ignore;
qi::rule<It, std::string(), qi::blank_type> ident, declaration, annot;
qi::rule<It, std::pair<std::string, std::string>(), qi::blank_type> combi;
qi::rule<It, Map(), qi::blank_type> start;
};
template <typename It>
void test(It f, It l)
{
grammar<It> p;
Map mappings;
bool ok = qi::phrase_parse(f, l, p, qi::blank, mappings);
if (ok)
{
for (auto it = mappings.begin(); it!=mappings.end(); ++it)
std::cout << "'" << it->second << "' annotated with name '" << it->first << "'\n";
}
if (f!=l)
std::cerr << "warning: remaing unparsed: '" << std::string(f,l) << "'\n";
}
int main()
{
const std::string input(
"#include <reality>\n"
"@bind VarName\n"
"uniform int myVariable;\n"
"// other stuff\n"
"@bind Var2Name\n"
"uniform int myVariable2;\n");
test(input.begin(), input.end());
}
これは印刷されます:
'myVariable2' annotated with name 'Var2Name'
'myVariable' annotated with name 'VarName'
liveworkspace.orgでライブのverbose(DEBUG)出力を参照してください