2016-04-04 18 views
0

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.)

Bu değişiklik neden derleme değil? Bir çözümden ne olup bittiğini anlamak için bir açıklama arıyorum.

cevap

2

Tamam, bu kadar yakından baktıktan sonra, tek bir std :: dizgisine dönüştürülebilen bir füzyon dizisi olan function_call_t türüne birden çok dizge eklemeye çalışıyorsunuz. Ancak, muhtemelen function_call kuralıyla ilgili sorunlara gidersiniz, çünkü bu özellik aslında tuple <std::string, optional <vector <std::string>>>. Ruhun bu yapıyı düzleştiren ve sorununuza neden olan sorunları olduğunu düşünürdüm, ancak şu anda bunu test etmek için bir derleyicim yok.

+0

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! –

İlgili konular