2012-07-16 75 views
3

我爲ParseKit寫了一個C語法,它完美地工作,但令我發瘋的是預處理語句。預處理器語句的正確符號定義是什麼?ParseKit - 如何正確處理預處理器語句?

這裏是什麼,我已經試過了簡單的例子...

@reportsCommentTokens = YES; 
@commentState = '/'; 
@singleLineComments = '//'; 
@multiLineComments = '/*' '*/'; 
@commentState.fallbackState = delimitState; 
@delimitState.fallbackState = symbolState; 

@start = Empty | comments | preprocessor; 

comments = comment*; 
comment = Comment; 

@symbols = '#include'; 

preprocessor = preprocessorIncludes; 

preprocessorIncludes = preprocessorIncludeStatement*; 
preprocessorIncludeStatement = preprocessorInclude quotedFileName*; 

preprocessorInclude = '#include'; 
quotedFileName = QuotedString; 

...但它不工作。將其作爲簡化的語法示例來捕獲註釋幷包含帶引號的語句(不適用於<>)。我試過這個語法上這個簡單的文件...

/* 
* Cryptographic API. 
* 
* RIPEMD-256 - RACE Integrity Primitives Evaluation Message Digest. 
* 
* Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC 
* 
* Copyright (c) 2008 Adrian-Ken Rueegsegger <[email protected]> 
* 
* This program is free software; you can redistribute it and/or modify it 
* under the terms of the GNU General Public License as published by the Free 
* Software Foundation; either version 2 of the License, or (at your option) 
* any later version. 
* 
*/ 

// Here's one line comment 

/* One line multiline comment */ 

#include "ripemd.h" 

/* 2nd one line multiline comment */ 

...它在/結束*一號線多行註釋* /,報告爲註釋標記,然後它靜靜地失敗。

所以我試圖分開 '的#include' 符號......

@symbolState = '#' '#'; 
@symbol = '#'; 
numSymbol = '#'; 

preprocessorInclude = numSymbol 'include'; 

...但它仍然沒有幫助。

也許Todd可以提供幫助,但是處理像'#include'這樣的符號的正確方法是什麼?

回答

2

開發者ParseKit這裏。

羅伯特,你的語法非常接近,但是我發現你使用嵌套的*(零或更多)修飾符會導致語法失敗。

我認爲問題是,你的@start語法的生產已經有Empty作爲一個頂級選項(|版與其他兩個生產),但隨後的子製作的commentspreprocessor都包含與*作品(零或更多)修飾符。那些* s應該確實是+(一個或多個)修飾符,因爲您已經對頂級Empty計入了零個案例。

我不完全確定,但我不認爲這是ParseKit獨有的問題,而是我懷疑語法是有問題的,而且這個問題可能在任何這樣的語法工具包中都可以看到。 (可能是錯誤的)

考慮到這一點,對語法的一些小調整已經爲我修好了。以下是經過編輯的語法與小的調整:

@reportsCommentTokens = YES; 
@commentState = '/'; 
@singleLineComments = '//'; 
@multiLineComments = '/*' '*/'; 
@commentState.fallbackState = delimitState; 
@delimitState.fallbackState = symbolState; 

@start = (comments | preprocessor)*; 

comments = comment+; 
comment = Comment; 

@symbols = '#include'; 

preprocessor = preprocessorIncludes; 

preprocessorIncludes = preprocessorIncludeStatement+; 
preprocessorIncludeStatement = preprocessorInclude quotedFileName; 

preprocessorInclude = '#include'; 
quotedFileName = QuotedString; 

通知我更換Empty在頂層有*。並且我的嵌套*+ s交換。

有了這個編輯語法,我得到所需的輸出(爲清楚起見稍微截斷):

[/* 
* Cryptographic API. 
... 
*/, // Here's one line comment, /* One line multiline comment */, #include, "ripemd.h", /* 2nd one line multiline comment */]/* 
* Cryptographic API. 
... 
*//// Here's one line comment//* One line multiline comment *//#include/"ripemd.h"//* 2nd one line multiline comment */^ 

此外,爲了找到問題,我改寫了語法簡單。這樣更容易找到問題。然後,我重新應用了我發現的原文語法。這是我提出的簡化語法,以防您感興趣。這是我覺得這個特別的語法在我的腦海:

@reportsCommentTokens = YES; 
@commentState = '/'; 
@singleLineComments = '//'; 
@multiLineComments = '/*' '*/'; 

@start = (comment | macro)*; 

comment = Comment; 

macro = include; // to support other macros, add: ` | define | ifdef` etc. 

include = '#' 'include' QuotedString; 
+1

「*我不能完全肯定,但我不認爲這是唯一的ParseKit問題*」不是。第一條規則使語法不是LL1語法,這意味着沒有上下文無關遞歸下降解析器可以解析它。 – JeremyP 2012-07-16 18:56:22

+1

託德,非常感謝!我試圖弄清楚語法有什麼問題,我正在創造很多變化,沒有一個是它的工作,這一個是最後的混亂:(再次感謝。 – robertvojta 2012-07-16 20:01:02