您的描述有点令人困惑(例如,您提到“用冒号分隔”,但我在输入中看不到任何冒号)。我假设您的意图是方括号中的项目是可选参数,括号中是强制参数,大括号中是“数据”。
在这种情况下,您的语法似乎是这样的:
func: name optionalParams '(' paramList ')' '{' data '}'
paramList: param |
paramlist ',' param
optionalParams: // empty
| '[' paramList ']'
name: WORD
param: WORD
data: WORD
这是一个足够简单的语法,Spirit 可能会很好地使用它。对于较大的语法,Spirit 往往会导致非常长的编译时间,但是这种语法足够小,编译时间应该是相当合理的。
显而易见的替代方法是编写一个下降解析器(如递归下降解析器,但在这种情况下不需要递归)。在这种情况下,您基本上会为语法的每个级别编写一个函数,让它读取适当的输入,然后返回一个结构(例如,一个向量)来保存它读取的数据。例如,optionalParams
可能是最难解析的(仅仅因为它是可选的):
typedef std::string param;
std::vector<param> read_optional_params(std::istream &in) {
std::vector<param> ret;
char ch = in.peek();
if (ch == '[' ) {
in >> ch;
param temp;
while (in >> temp && temp != "]")
ret.push_back(temp);
if ((ch=in.peek) == ',')
in >> ch;
}
return ret;
}
在顶层,你会有类似的东西:
function read_func(std::istream &in) {
std::string name = read_name(in);
std::vector<param> optional_params = read_optional_params(in);
std::vector<param> mandatory_params = read_mandatory_params(in);
std::string data = read_data(in);
if (in.fail()) {
// malformed input
}
function func = function(name);
for (int i=0; i<optional_params.size(); i++)
func.addOptionalParam(optional_params[i]);
for (int i=0; i<mandatory_params.size(); i++)
func.addMandatoryParam(mandatoryParams[i]);
func.setData(data);
return func;
}