このタイプの構文を持つforループを解析しようとしています:
for(loop = 1:10) {
}
私の文法には次のような規則があります。
genericString %= lexeme[+(char_("a-zA-Z"))];
intRule %= int_;
commandString %= lexeme[+(char_ - '}')];
forLoop %= string("for")
>> '('
>> genericString // variable e.g. c
>> '='
>> (intRule | genericString) // variable e.g. i
>> ':'
>> (intRule | genericString) // variable e.g. j
>> ')' >> '{'
>> (forLoop | commandString)
>> '}';
これは上記の単純な例では機能しますが、次のネストされた例の解析に失敗します。
for(loop = 1:10) {
for(inner = 1:10) {
}
}
パーサーがブレースの配置と「混乱している」ためだと思います。http://boost-spirit.com/distrib/spirit_1_7_0/libs/spirit/example/fundamental/lazy_parser.cppに示されているようなことをする必要があると思います(ああ、フォローするのは難しいと思いました)。
乾杯、
ベン。
編集1:
私は今、forLoop内ではなく、commandString(以下ではnestedBlockと呼ばれます)からの再帰を処理する方がよいと考えています。
forLoop %= string("for")
>> '('
>> genericString // variable e.g. c
>> '='
>> (intRule | genericString) // variable e.g. i
>> ':'
>> (intRule | genericString) // variable e.g. j
>> ')'
>> nestedBlock;
nestedBlock %= lexeme['{' >> -(char_ - '}' - '{')
>> -nestedBlock
>> -(char_ - '}' - '{')
>> '}'];
これは大規模なboost::spritiエラーで失敗しています。ルールは次のように定義されます。
qi::rule<Iterator, std::string(), ascii::space_type> nestedBlock;
qi::rule<Iterator, Function(), ascii::space_type> forLoop;
関数はboost::variantsの構造体です
編集2:
これが私が今持っているものです(ネストされた構造の有無にかかわらず動作するように設計されています):
commandCollection %= *start;
forLoop %= string("for")
>> '('
>> genericString // variable e.g. c
>> '='
>> (intRule | genericString) // variable e.g. i
>> ':'
>> (intRule | genericString) // variable e.g. j
>> ')'
>> '{'
>> commandCollection
>> '}';
start %= loadParams | restoreGenomeData | openGenomeData | initNeat | initEvo |
initAllPositions | initAllAgents | initCoreSimulationPointers |
resetSimulationKernel | writeStats | restoreSimState |
run | simulate | removeObjects | setGeneration |
setParam | getParam | pause | create | reset |
loadAgents | getAgent | setAgent | listParams | loadScript | forLoop
| wait | commentFunc | var | add | sub | mult | div | query;
そして、commandCollectionルールを次のように宣言します。
qi::rule<Iterator, boost::fusion::vector<Function>, ascii::space_type> commandCollection;
私はこれが私が期待するようにうまくいくと思いました。commandCollectionは、boost ::fusion::vectorに格納する必要がある0個以上のコマンドとして定義されています。ただし、Function()構造体からベクトルを抽出する場合(開始ルールがFunction()イテレーターを使用することを念頭に置いて)、何らかの理由で型がboost ::fusion :: vectorとして識別されないため、抽出されました。理由はわかりません...
しかし、もし私が
commandCollection %= start;
ルールを次のようにデカールします
qi::rule<Iterator, Function(), ascii::space_type> commandCollection;
次に、データを単一のFunction()構造体として抽出しようとすると、正常に機能します。ただし、複数のコマンド(* start)をある種のコンテナーに格納したいと思います。std :: vectorも試してみましたが、これも失敗しました。