2012-07-16 72 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