2015-08-03 47 views
0

我在Linux上使用Flex & bison。我已經有以下設置:如何逃避flex關鍵字

//令牌 CREATE {返回令牌:: CREATE;}
的模式{返回令牌:: SCHEMA; }
RECORD {return token :: RECORD;}
[_a-zA-Z0-9] [_a-zA-Z0-9] * {yylval-> strval = strdup(yytext);}返回TOKEN :: NAME;}
...
//規則 CREATE架構名稱...
創建記錄NAME ... ...

一切工作就好了。但是,如果用戶輸入:「create schema record ...」(其中'record'是要創建的模式的名稱),Flex會報告錯誤,因爲它將'record'作爲標記匹配,並且正在查找規則「創建模式記錄」。我明白,關鍵字可以逃脫,但這會讓用戶體驗變得尷尬。我的問題是:

「?我怎樣才能設計出上面的規則,使其接受‘創建模式記錄......’,這輸入到‘創建模式名稱...’匹配

謝謝!

回答

0

您不應該這樣做,出於同樣的原因,您不能在名爲forwhileclass的C++中使用變量。但如果你真的想,看看Start Conditions(這將是凌亂)。

4

「半保留」單詞在具有大量保留字的語言中很常見。 (即使是現代的C++也有這樣幾個:overridefinal)。但是它們給傳統掃描儀帶來了一些困難,傳統掃描儀通常假定關鍵字是關鍵字。

檸檬語法分析器生成器並非巧合地設計用於解析SQL,它具有一個有用的「回退」功能作爲其錯誤處理的一部分,其中上下文中無效的令牌可由另一個令牌替換(不會更改語義值)。不幸的是,野牛沒有實現這個功能,也沒有任何其他解析器生成器我知道。但是,在很多情況下,可以在Bison語法中實現該功能。例如,在這裏介紹的簡單的例子,我們可以代替:

create_statement: CREATE RECORD NAME ... 
       | CREATE SCHEMA NAME ... 

有:

create_statement: CREATE RECORD name 
       | CREATE SCHEMA name 
name: NAME 
    | CREATE 
    | RECORD 
    | SCHEMA 
    | ... 

顯然,照顧需要採取的(半)的替代品的清單中的關鍵字name在使用name的上下文中無效。這可能需要定義各種name製作,適用於不同的上下文。 (這是檸檬風格的後備更方便的地方。)

如果這樣做,重要的是要正確設置關鍵字的語義值,無論是由掃描儀還是由非name -終奌站。如果只有一個非終端,那麼在歸約操作中執行它可能更有效(因爲它避免了不必要的分配和取消分配字符串,其中釋放會使出現關鍵字的其他語法規則複雜化),所以該name規則實際上是這樣的:

name: NAME 
    | CREATE { $$ = strdup("CREATE"); } 
    | RECORD { $$ = strdup("RECORD"); } 
    | SCHEMA { $$ = strdup("SCHEMA"); } 
    | ... 

有,當然有很多其他可能的方法來處理語義值問題。