2011-05-24 63 views
2

我正在努力學習Boost Spirit並作爲練習,我試着用Boost Spirit Classic解析SQL INSERT statement用Boost Spirit Classic解析SQL INSERT

這是我試圖解析字符串:

INSERT INTO example_tab (cola, colb, colc, cold) VALUES (vala, valb, valc, vald); 

從這個SELECT example我創建了這個小語法:

struct microsql_grammar : public grammar<microsql_grammar> 
{ 
    template <typename ScannerT> 
    struct definition 
    { 
     definition(microsql_grammar const& self) 
     { 
      keywords = "insert", "into", "values"; 

      chlit<>  LPAREN('('); 
      chlit<>  RPAREN(')'); 
      chlit<>  SEMI(';'); 
      chlit<>  COMMA(','); 

      typedef inhibit_case<strlit<> > token_t; 

      token_t INSERT  = as_lower_d["insert"]; 
      token_t INTO  = as_lower_d["into"]; 
      token_t VALUES  = as_lower_d["values"]; 

      identifier = 
       nocase_d 
       [ 
        lexeme_d 
        [ 
         (alpha_p >> *(alnum_p | '_')) 
        ] 
       ]; 

      string_literal = 
       lexeme_d 
       [ 
        ch_p('\'') >> +(anychar_p - ch_p('\'')) 
        >> ch_p('\'') 
       ]; 

      program =    +(query); 

      query =     insert_into_clause >> SEMI; 

      insert_into_clause = insert_clause >> into_clause; 

      insert_clause =   INSERT >> INTO >> identifier >> LPAREN >> var_list_clause >> RPAREN; 

      into_clause =   VALUES >> LPAREN >> var_list_clause >> RPAREN; 

      var_list_clause =  list_p(identifier, COMMA); 
     } 

     rule<ScannerT> const& start() const { return program; } 

     symbols<> keywords; 

     rule<ScannerT> identifier, string_literal, program, query, insert_into_clause, insert_clause, 
      into_clause, var_list_clause; 
    }; 
}; 

使用最小的測試它:

void test_it(const string& my_example) 
{ 
    microsql_grammar g; 

    if (!parse(example.c_str(), g, space_p).full) 
    { 
       // point a - FAIL 
     throw new exception(); 
    } 

    // point b - OK 
} 

不幸的是,它總是進入A點並拋出異常。由於我是新手,我不知道我的錯誤在哪裏。我有兩個問題:

  1. 使用Boost Spirit時,調試解析錯誤的正確方法是什麼?
  2. 爲什麼解析在這個例子中失敗?
+0

我試過你的語法,它解析上面的輸入。如果您提供的輸入具有任何尾隨空格或換行符,它們將阻止parse_info <> :: full標誌被設置,但parse_info <> :: hit標誌將被設置。 – equackenbush 2011-05-24 20:45:49

回答

3

爲了得到知名度到什麼是無法解析,解析的結果賦值給一個parse_info <>,然後登錄/檢查parse_info <> ::停止字段,在這種情況下應該是一個const char *指向你輸入的與你的語法相匹配的字符串的最後一個字節。

microsql_grammar g; 

parse_info<std::string::const_iterator> result = parse(example.begin(), example.end(), g, space_p) 
if (!result.full) 
{ 
    std::string parsed(example.begin(), result.stop); 
    std::cout << parsed << std::endl; 

      // point a - FAIL 
} 

// point b - OK 

道歉,如果這不能編譯,但應該是一個起點。

+0

謝謝!我從文件中讀取字符串,但沒有注意到字符串上附加了一個換行符,因此它沒有完全匹配字符串。 – 2011-05-26 14:29:58

相關問題