首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在EBNF/Tatsu中定义默认规则?

如何在EBNF/Tatsu中定义默认规则?
EN

Stack Overflow用户
提问于 2018-11-08 21:17:46
回答 1查看 133关注 0票数 0

我在我的EBNF和Tatsu实现中有一个问题,Tatsu的提取语法EBNF:

代码语言:javascript
复制
define  ='#define' constantename [constante] ;
constante = CONSTANTE ;  
CONSTANTE = ( Any | ``true`` ) ;
Any = /.*/ ;  
constantename = (/[A-Z0-9_()]*/) ;

当我使用以下命令测试时:

代码语言:javascript
复制
#define _TEST01_ "test01"
#define _TEST_
#define _TEST02_ "test02"

我得到了:

代码语言:javascript
复制
[
    "#define",
    "_TEST01_",
    "\"test01\""
],
[
    "#define",
    "_TEST_",
    "#define _TEST02_ \"test02\""
]

但我想要的是:

代码语言:javascript
复制
[
    "#define",
    "_TEST01_",
    "\"test01\""
],
[
    "#define",
    "_TEST_",
    "true"
],
[
    "#define",
    "_TEST02_",
    "\"test02\""
]

我的错误在哪里?

非常感谢。

EN

回答 1

Stack Overflow用户

发布于 2018-11-09 01:24:44

问题是默认情况下,Tatsu会跳过元素之间的空白,包括换行符。因此,当您将规则'#define' constantename [constante]应用于输入时:

代码语言:javascript
复制
#define _TEST_
#define _TEST02_ "test02"

它首先将#define'#define'匹配,然后跳过空格,然后将_TEST_constantename匹配,然后跳过换行符,然后将#define _TEST02_ "test02"ANY匹配(通过constante)。

请注意,如果没有换行符,这正是您想要的行为(我假设):

代码语言:javascript
复制
#define _TEST_ #define _TEST02_ "test02"

在这里您需要输出["#define", "_TEST_", "#define _TEST02_ \"test02\""],对吗?在这种情况下,至少C预处理器会以同样的方式处理它。

所以这告诉我们换行符是很重要的。因此,你不能忽视它。您可以告诉Tatsu只忽略制表符和空格(而不是换行符),方法是在创建解析器时将whitespace = '\t '作为选项传递,或者将下面这一行添加到语法中:

代码语言:javascript
复制
@@whitespace :: /[\t ]+/

现在你需要在换行符应该放到的任何地方显式地提到换行符,所以你的规则变成:

代码语言:javascript
复制
define  ='#define' constantename [constante] '\n';

现在很明显,常量,如果存在,应该出现在换行符之前,所以对于行#define _TEST_,它会意识到没有常量。

请注意,您还需要一个匹配空行的规则,因此空行不是语法错误。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53208564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档