2016-05-11 7 views
1

以下のEBNFを解析しています(コードにコメントがあります)。オプションのコメントのSTRING部分を解決しようとしています。(テスト文字列に余分なコメントとして書かれています)Pyparsing:SQLヒントを解析する方法

from pyparsing import * 

# SQL HINT EBNF 
''' 
{ /*+ hint [ string ] 
     [ hint [ string ] ]... */ 
| --+ hint [ string ] 
     [ hint [ string ]... 
} 
''' 

test_string = "/*+ALL_ROWS extra comment FIRST_ROWS CACHE*/" 

LCOMMENT = Literal("/*+") 
RCOMMENT = Literal("*/") 

grammar = Forward() 

hint_all_rows = Literal("ALL_ROWS") 
hint_first_rows = Literal("FIRST_ROWS") 
hint_cache = Literal("CACHE") 

comment_in_hint = Word(printables) 

all_hints = (hint_all_rows | hint_first_rows | hint_cache)+ ZeroOrMore(comment_in_hint) 

grammar << all_hints + ZeroOrMore(grammar) 

all_grammar = LCOMMENT + grammar + RCOMMENT 

p = all_grammar.parseString(test_string) 

print p 
+0

"extra"と "comment"はパーサのどこにも表示されず、 'Word(printables) 'のような非空白文字のグループを受け入れるキャッチオール型の要素はありません。 – PaulMcG

+0

Paul、それは速い応答です。そして、今私は私の仕事を含めていないために少し愚かな感じ! (私が経験豊富なSOのユーザーではないことがわかるように)..私はあなたがすでに推測したように、キャッチオールで私のOPを編集するでしょう。しかし、これは末尾の2つのヒント、FIRST_ROWSとCACHEを捕まえる原因となります。 –

+0

そして、私は編集でテストに入ることを試みましたが、私はそのコードにcatch(all)(comment_in_hint)を追加しました(RCOMMENT)を食べます。 –

答えて

0

これは今OPのコメントのポールマクガイアの助けのおかげで実行されるコードです。最初に答えを設定するとき、私は前方関数を取り除きました。しかし、結果の名前を別の要素に結びつけてコードをチェックすると、ここでの最初の答えは、最初のヒント以外のすべてをコメントとして分類していることに気付きました。だから、私は前向きを保ちましたが、Paulsの他の提案を利用しました。

from pyparsing import * 

# SQL HINT EBNF 
''' 
{ /*+ hint [ string ] 
     [ hint [ string ] ]... */ 
| --+ hint [ string ] 
     [ hint [ string ]... 
} 
''' 

LCOMMENT = Literal("/*+") 
RCOMMENT = Literal("*/") 

grammar = Forward() 

hint_all_rows = Keyword("ALL_ROWS") 
hint_first_rows = Keyword("FIRST_ROWS") 
hint_cache = Keyword("CACHE") 

comment_in_hint = Word(printables, excludeChars='*') 

grammar = Forward() 

all_hints = (hint_all_rows | hint_first_rows | hint_cache).setResultsName("Hints", listAllMatches=True) + Optional(comment_in_hint)("Comments*") 

grammar << all_hints + ZeroOrMore(grammar) 

all_grammar = LCOMMENT + grammar + RCOMMENT 

p = all_grammar.parseString("/*+ ALL_ROWS aaaaaaa FIRST_ROWS bbbbb */") 

print p["Hints"] 

print p["Comments"]