我正在尝试解析具有这种语法的循环:
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:
我现在认为处理来自 commandString(下面称为 nestedBlock)而不是在 forLoop 中的递归会更好,例如:
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 定义为 0 个或多个命令,这些命令应存储在 boost::fusion::vector 中。但是,当我从 Function() 结构中提取向量时(请记住,开始规则使用 Function() 迭代器),由于某种原因,该类型未被识别为 boost::fusion::vector 所以不能提取。我不确定为什么...
但是,如果我有
commandCollection %= start;
并将规则标记为
qi::rule<Iterator, Function(), ascii::space_type> commandCollection;
然后尝试将数据提取为单个 Function() 结构,它工作正常。但我希望它能在某种容器中存储多个命令(即 *start)。我也尝试过使用 std::vector 但这也失败了。