2016-11-03 19 views
0

激勵例子
好:如何允許OK場所,並禁止壞的有升壓精神

SELECT a, b, c d,e FROM t1 

不好:

SE L ECT a, b, c d,e FR OM t1 

SELECTa, b, c d,eFROMt1 

因此,大家可以看到這裏的問題是,一些空間都OK (例如,在SELECT和a,b,c之間),有些是不好的(SE L ECT),有些是必需的(在關鍵字之前/之前)。

所以我的問題是什麼成語用在這裏,因爲如果我使用space船長與phrase_parse它可以讓壞的空間,如果我想允許良好的空間沒有隊長解析器成爲散落着*char_(' ')

+0

聲音對我來說,你要找的是一個正則表達式;或者更好,檢查你的SQL查詢的結果? – UKMonkey

+0

這主要是關於解析與提升精神,這只是一個玩具的例子,這種真正的問題不能用正則表達式很好地解決 – NoSenseEtAl

+2

如果你提供一個邏輯定義什麼是「好」或「壞」空間意味着作爲一個技術規範,那麼它可以直接轉換成代碼。但是,像「好」或「壞」這樣含糊不清的概念是不能直接翻譯成軟件的。 –

回答

1

你是什麼尋找就是解析。

這不是關於接受/拒絕「好」或「壞」空間。它是關於嘗試識別輸入的內容,如果不能,則拒絕它。

在這種情況下,我們開始了(徹底簡化)語法有問題的聲明:

select_statement ::= 'select' field_list 'from' table 

所以,你在第一個標記讀取。如果它是SESELECTa,您會拒絕該聲明爲無效,因爲這些語法都不符合您的語法。幾乎任何像樣的解析器生成器(包括但當然不限於靈)使這相當微不足道的 - 你指定什麼可以接受的,做什麼,如果輸入的是接受,並將其與調用,對於交易輸入不符合指定的語法。

至於你怎麼做標記化入手,這是通常非常簡單,通常可以是基於正則表達式(例如,許多語言一直在使用lex和Flex,衍生物等來實現其使用regexen來指定標記)。

這樣的事情,你直接指定關鍵字的語言,所以你有什麼,說,當它匹配「選擇」,它應該返回,作爲一個令牌。然後,對於通常運行類似`[_a-zA-Z] [_ a-zA-Z0-9] *'的標識符,您可以使用某種標識符*'(「標識符以下劃線或字母開頭,後跟任意數量的下劃線,字母或數字「)。在上面的例子中,這完全足以找到並返回「SE」和「SELECTa」作爲「壞」示例中的第一個令牌。然後

解析器將檢測到它接收到的第一件事是一個標識符,而不是一個鍵字,在該點它將(大概)被拒絕。

+0

少數情況下,「您可以使用正則表達式解決您的問題」不會給您帶來兩個問題,因爲沒有人會爲「標識符」使用瘋狂的模式。 – Yakk

+1

這種方法的精神翻譯將是使用Spirit Lex標記器。我不會推薦它,因爲它使Spirit的使用複雜化了,我認爲它不會再打到甜蜜的地方 – sehe

3

您需要將您的關鍵字標記爲qi::lexeme[]

此外,你可能要像boost::spirit::repository::qi::distinct,以避免2 \

見例如解析SELECT2SELECT其次

+0

很好的答案,只是給它一些更多的信息我認爲在我的例子中這從你的其他答案是真的:「如果你正在構建一個非常強大的通用語言語法,那麼你應該考慮使用Spirit Lexer。」如果我錯了,憤怒的評論回覆。 :) – NoSenseEtAl