2012-04-15 35 views
2

我在想,如果所有的編程語言保留關鍵字?說If,While是保留的關鍵詞。我們不應該使用它作爲普通變量或函數名稱,如果我有If = 3是非法的。所以編譯器會在sanner階段產生錯誤。如果一種語言允許程序員使用保留的關鍵字If作爲變量名稱或函數名稱。編譯器如何處理這個問題?這是否在掃描儀或解析器中處理?語義分析應該做什麼?編程語言中保留的關鍵字

更新: 我明白這不是一個很好的做法,但對於大多數的真正原因/所有的編程語言不支持,這是因爲掃描儀或者解析器不能做acurately掃描語言或解析語言或什麼是真的幕後?謝謝。

+0

這樣的erm能力不僅會讓編譯器「迷惑」,而且會讓人們用這種語言閱讀代碼。那爲什麼放棄這個呢? – kirilloid 2012-04-15 23:54:19

回答

4

你絕對可以做這樣的事情,但顯然它會破壞源代碼的直觀性。想象一下:

if if == 1 

就實際執行它而言,詞法分析器根本不需要改變。如果詞法分析器在源中匹配「if」,它會返回一個帶有IF類型的標記。假設我們有以下的賦值語句,將if是一個變量名,它越來越賦值爲1

if <- 1; 

詞法分析器的令牌流被送進分析器是:

IF, LARROW, INTLITERAL, SEMICOLON 

我可能有下列作品描述的賦值語句(\ W整數rvals):

assignStmt::= id:i LARROW intExpr:e SEMICOLON {: RESULT = new AssignmentStatement(i, e) :} 
intExpr::= INTLITERAL:i {: RESULT = i.intVal; :} 
id::= ID:i {: RESULT = i.strVal; :} 

LARROWIDIF,INTLITERALSEMICOLON是終端,它們是詞法分析器返回的令牌,並且assignStmt,idintExpr是非終端。 ID代表一個標識符(例如類別/變量/方法名稱)。

在if語句生產失敗後,我們最終會輸入賦值語句的第一個生成語句。我們擴大id非終端,其唯一生產是ID,但我想匹配的令牌是IF,所以assignStmt生產完全失敗。

對於我的語言,讓一個變量被命名爲「如果」所有我需要做的就是:

assignStmt::= id:i LARROW intExpr:e SEMICOLON {: RESULT = new AssignmentStatement(i, e) :} 
intExpr::= INTLITERAL:i {: RESULT = i.intVal; :} 
id::= ID:i {: RESULT = i.strVal; :} 
    |IF {: RESULT = "if"; :} 

注意|定義的非終端的替代產品。現在我們爲id非終端進行第二次生產,它與當前令牌匹配,並最終導致與賦值語句匹配。

AssignmentStatement被定義爲AST節點如下:

class AssignmentStatement { 
    String varName; 
    int intVal; 
    AssignmentStatement(String s, int i){varName = s; intVal = i; } 
} 

一旦解析器決定源是語法正確的,不應該有其他的影響。變量的名稱不應該影響編譯的後期階段,也就是說,如果您不創建允許發生這種情況的條件。

+0

感謝您的詳細解釋,這正是我所期待的。 – 2012-04-16 03:47:50

0

嗯,我不能想到沒有保留關鍵字的任何編譯語言;它更簡單得多,並且很少有充分的理由使用這些保留的關鍵字('if'不是一個好的變量名)。

在PHP中,變量是以美元符號開頭的,所以我認爲一種語言可以用這種方式實現它(使用非字母前綴變量,所以你可以有$ if)。我想這可能會起作用,儘管這樣做沒有多大用處。

1

爲什麼你要做到這一點,即使你可以?

它所能做的只是讓不可維護的代碼。

if (a==b) - 是一個if表達式或調用函數if傳遞布爾arg?

我想說,如果任何語言確實讓你這樣做,它可能是一個奇怪的學術與3用戶的事情。

[編寫關於石棉的內衣將用於從無情的3個用戶;-)燃燒]

-1

我不認爲任何這樣的語言存在。 所有的信息語言都是基於語法的,也就是說一組規則必須構建的規則。這樣,您可以證明代碼在結構上是有效的。 如果您想允許切換名稱,則必須有一種方法來「更改」語法,以確保代碼驗證保持正確。

在更實際的層面上,爲什麼還要做這樣的事呢?保留關鍵字有什麼問題?它們非常有用,至少每個人都以同樣的方式講同一種語言。 你甚至不會用現實世界的語言去想這樣的事情......想象一下,如果你開始轉換詞語的意思!沒有人會了解任何東西!

+0

請看PL/1 ... – 2013-05-08 05:05:18

1

編程語言傾向於保留單詞,因爲人們喜歡將詞法掃描器放在解析器之前。詞法掃描器會將源代碼轉換爲一系列的標記,所以你最終可能會得到一個「>>」標記,並說所有這些標記都是移位操作符,然後除了作爲其他部分之外,你不能將這些字符用於其他任何東西令牌(如帶引號的字符串),它是或曾經是C++常見的問題。其他的詞如「if」是相同的,它變成某種「if」標記,並且每當解析器看到「if」標記時,它將它視爲某個條件構造的第一部分。另一個例子是JavaScript,您可以在其中編寫

JSON。字符串化({吧:2})

,但你不能寫

JSON.stringify({VAR:2})

因爲 「變種」 是一個 「無功」 的道理,但 「巴」 是隻是一個像任何其他標識符。

+0

作爲blackcompe的回答,如果允許'id-> IF',那麼我們可以把它當作標識符。 – 2012-04-16 03:50:37

+0

從詞法分析器到分析器推遲了相同的問題,需要另一個層來修復它。另外請記住,您不僅需要接受有效的代碼。如果程序錯誤,您還必須能夠在幾乎正確的位置輸出正確的錯誤消息。模糊的語法使得難度更大。 – 2012-04-16 10:56:55

0

允許任意關鍵字的一種方法是對所有非標識符語法變量使用非字母符號。 APL採用這種方法,Smalltalk也是如此(在Smalltalk-80中,有6個保留字,但它們都具有類似變量的語義;通常爲關鍵字的東西,如條件,是語法上常規的消息)。