Christian Ridderström wrote: > Um... I don't understand it... OTOH I've never used Boost Spirit, > but that means it's not obvious if you're unfamiliar with that. > Could you give a link for Boost Spirit? (and maybe a few comments?)
http://www.boost.org/libs/spirit/index.html http://www.boost.org/libs/spirit/phoenix/index.html Really well written docs, but a lot of them ;-) > And here's a part of the parser. But I don't understand it, guess I > don't know what for instance 'var' or 'self' mean/do... Is > 'expression' a variable? (what type?) 'expression' is a variable of type a 'rule' --- a class that stores the parser definition. 'self' is just the me being lazy --- field and field_name are actually stored in the parent class 'owning' this impl struct. So ignore it. 'var' and 'arg1' are phoenix variables that 'bind' to, say, field_name and NOW (when the expression block of code is invoked) and thereafter allow field_name to be set when the data set is actually parsed (some time LATER). This is 'lazy evaluation' and is the key concept behind lambda expressions. So, uint_p[resize(var(field), arg1)] means * parse a uint. (An error is thrown if the data set doesn't contain a uint at this point.) * arg1 is a placeholder for this parsed uint. Use it to resize 'field'. All this is lazy code. The data set is not parsed when 'expression' is created. So, resize is a lazy function invoking field.resize(size_type) at the time that the uint is read. Bloody clever actually. > >> vector<double> & field = ...; >> string & field_name = ...; >> >> expression = >> f_str_p(var(self.field_name)) >> >> str_p("NNODES") >> >> >> uint_p[resize(var(field), arg1)] >> >> >> for_p(var(index) = 1, >> var(index) <= size(var(field)), >> var(index)++) >> [ >> limit_d(cref(index), cref(index))[uint_p] >> >> real_p[var(field)[var(index)-1] = arg1] >> ]; -- Angus