如何在Jison中检测换行?

poo*_*zko 1 parsing bison jison

我有一段Jison的代码,看起来像这样:

%lex
%options flex

%{
if (!('regions' in yy)) {
    yy.regions = [];
}
%}

text                [a-zA-Z][a-zA-Z0-9]*

%%

\s+                 /* skip whitespace */
\n+                 return 'NL';
","                 return ',';
"-"                 return '-';
"["                 return '[';
"]"                 return ']';
{text}              return 'TEXT';
<<EOF>>             return 'EOF';

/lex

%start expressions

%%

expressions
    : content EOF
        {
            console.log(yy.regions);
            return yy.regions; 
        }
    | EOF
        {
            console.log("empty file");
            return yy.regions; 
        }
    ;

content
    : line NL content
        { console.log("NL"); }
    | line content
        { console.log("no NL"); }
    //| line NL
    //    { console.log("parsing line with NL"); }
    | line
        { console.log("parsing line"); }
    ;

line 
    : '[' text ']'
        { yy.regions.push($2); $$ = $2; }
    ;

text
    : TEXT
        { $$ = $1; }
    ;
Run Code Online (Sandbox Code Playgroud)

这是我目前的输入(我从计划的最基本构造开始,并希望从那里开始构建):

[sectionA]
[sectionB]
[sectionC]
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是未检测到新行。它总是进入line content永不进入line NL content。稍后,我想解析更像这样的内容:

[sectionA]
something1, something2, something3
something4, something5, something6

[sectionB]
something4, something5, something6

[sectionC]
something4, something5, something6
something4, something5, something6
something4, something5, something6
Run Code Online (Sandbox Code Playgroud)

将来这会变得更加复杂,但是我的最初想法是将其分解为每行(在许多情况下,新行将用作分隔符)。我对这些东西是完全陌生的,所以我可能对解决这个问题有完全错误的想法。所以我的问题是如何检测到新线?同样,如果有更好的方法来解决我的问题,那么任何建议都将受到欢迎。谢谢。

ric*_*ici 5

这两个规则都将与换行符匹配:

\s+                 /* skip whitespace */
\n+                 return 'NL';
Run Code Online (Sandbox Code Playgroud)

由于第一个是第一个,它将获胜。(Flex会警告您第二条规则未使用,但我不相信jison会进行该分析。)

但是,更改规则的顺序将无济于事,因为第一个规则将匹配SPACE NL,因此如果换行符前面有空格,则将其吞下。您需要更改空格规则以仅匹配不是换行符的空格。

一种可能性是:

\n\s*     return 'NL';
[^\S\n]+  /* ignore whitespace other than newlines */
Run Code Online (Sandbox Code Playgroud)

第一个模式将与换行符匹配,后跟任何空格序列,这意味着它将与多个换行符匹配。NL当输入中有空行时,这将避免返回多个令牌。除非空白行很重要,否则可能就是您想要的。

第二种模式避免匹配任何换行符,因此它不会与第一种模式冲突。

某些人担心Windows行尾(\r\n)的使用,但是由于Java语言\s包含了\r,所以这里没有真正的问题。该\r规则将被第二条规则忽略,而被第一条规则所\n识别。\r?\n\s*如果您认为必要的话,可以将第一条规则更改为效率,但结果可能不会更快。