首页 > 解决方案 > 如何正确处理新行

问题描述

我正在尝试在任何地方创建一种在我的代码中忽略 NewLines 的语言

所以我在我的词法分析器中声明只是 [\n] 没有返回任何东西,所以它可以被忽略这工作得很好,它忽略了代码中的每一个 newLine 但我想实现一个不应该忽略它的规则,规则是:如果代码是这样的:

!Array_Library;

!Loop_Library;

应该被接受

!Array_Library;!Loop_Library; 

不应该被接受,因为两个库之间必须有一个 newLine

我试图让我的词法分析器在遇到 \n 时返回 NewLine 但是我会失去“在任何地方忽略 NewLines”规则

标签: bisonflex-lexer

解决方案


做这种事情的通常方法是使用词法分析器开始条件(有时称为开始状态),并让词法分析器或解析器在适当的时间设置当前的开始条件。您可以在 flex 的文档中找到这方面的信息,但基本上,您的词法分析器将类似于:

%s SPECIAL

%%

<INITIAL>[\n]     ;   /* normally ignore newlines */
<SPECIAL>[\n]     return *yytext;   /* but not in the SPECIAL state */

/* other flex rules */

%%

void enableNewlines() { BEGIN(SPECIAL); }
void disableNewlines() { BEGIN(INITIAL); }

然后在您的野牛代码中,您可能会有类似的操作

input: bang command '\n'  {
    /* handle the command */
    disableNewlines(); }

bang: '!'  { enableNewlines(); }

基本思想是,当你识别出足够多的东西来知道有一个必需的换行符出现时,你进入那个特殊的开始状态,然后一旦你解析了换行符,你就会回到“正常”开始状态。您需要注意确切的顺序,因为在某些情况下,bison 会在减少操作之前提前读取一个标记(获得前瞻)。

另一种可能更简单或更复杂的方法是让词法分析器始终返回换行符,并让您的语法在它们可能出现的任何地方显式地忽略它们。这可能很冗长(语法中有很多地方)。


推荐阅读