Sadece eğlence için küçük bir derleyici yazıyorum ve dilbilgisi tanımlamak için Boost Spirit Qi kullanıyorum. Şimdi dilbilgisinde küçük değişiklikler yapmak istiyorum. Ne yazık ki bu değişiklikler derlenmeyecek ve bunun neden böyle olduğunu anlamak istiyorum.Boost Spirit Qi: Küçük bir kural değişikliğinde hata derleme
Değiştirmek istediğim koddan bir kod parçacığı. Umarım verilen bilgiyi anlamak için yeterlidir. Tam kod biraz büyüktür, ancak ona bakmak veya test etmek isterseniz (Makefile ve Travis CI sağlanmıştır), bkz. https://github.com/Kruecke/BFGenerator/blob/8f66aa5/bf/compiler.cpp#L433.
typedef boost::variant<
function_call_t,
variable_declaration_t,
variable_assignment_t,
// ...
> instruction_t;
struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
grammar() : grammar::base_type(program) {
instruction = function_call
| variable_declaration
| variable_assignment
// | ...
;
function_call = function_name >> '(' > -(variable_name % ',') > ')' > ';';
// ...
}
qi::rule<iterator, instruction::instruction_t(), ascii::space_type> instruction;
qi::rule<iterator, instruction::function_call_t(), ascii::space_type> function_call;
// ...
};
Şimdiye kadar her şey gayet iyi çalışıyor. Şimdi son noktalı virgül (> ';'
) ayrıştırma işlemini function_call
kuralından instruction
kuralına taşımak istiyorum. Benim kod artık şöyle görünür: karakter ayrıştırıcı ';'
herhangi niteliğini verim vermez ve bu ayrıştırıcı konumlandırılmış nerede bu yüzden önemli olmamalı çünkü Benim anlayış
struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
grammar() : grammar::base_type(program) {
instruction = (function_call > ';') // Added trailing semicolon
| variable_declaration
| variable_assignment
// | ...
;
// Removed trailing semicolon here:
function_call = function_name >> '(' > -(variable_name % ',') > ')';
// ...
}
kurallar gerçekten değişmemiştir. Ancak, bu değişiklik derlemek olmaz:
/usr/include/boost/spirit/home/support/container.hpp:278:13: error: no matching function for call to ‘std::basic_string<char>::insert(std::basic_string<char>::iterator, const bf::instruction::function_call_t&)’
c.insert(c.end(), val);
^
(Bu hata instruction = ...
hattan geliyor.)
Kesinlikle haklısınız! 'Function_call_t' içinde sadece bir 'std :: string' olması asla istediğim şey değildi, bu yüzden bir önceki kodumun ilk sırada yer alması beni çok şaşırttı! Yapıma bir "std :: vector variable_names" ekledim ve bu sorunu derhal giderdim. Çok teşekkürler! –