如何检测 Jison 中的新行?
How to detect new line in 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(); $$ = ; }
;
text
: TEXT
{ $$ = ; }
;
这是我目前输入的样子(我从我计划拥有的最基本的结构开始,我想从那里开始构建它):
[sectionA]
[sectionB]
[sectionC]
我遇到的问题是未检测到新行。它总是进入 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
将来这会变得更复杂一些,但我最初的想法是将其分解为每行(在许多情况下,新行将用作分隔符)。我对这些东西完全陌生,所以我可能对如何解决这个问题有一个完全错误的想法。所以我的问题是如何检测新行?此外,如果对我正在尝试做的事情有更好的方法,我们非常欢迎任何建议。谢谢。
这两个规则都将匹配换行符:
\s+ /* skip whitespace */
\n+ return 'NL';
既然先到先得,就赢了。 (Flex 会警告您未使用第二条规则,但我不相信 jison 会进行该分析。)
虽然改变规则的顺序没有帮助,因为第一条规则将匹配 SPACE NL ,从而吞下换行符(如果它前面有空格)。您需要更改空格规则以仅匹配不是换行符的空格。
一种可能性是:
\n\s* return 'NL';
[^\S\n]+ /* ignore whitespace other than newlines */
第一个模式将匹配换行符后跟任何空格序列,这意味着它将匹配多个换行符。当输入中有一个空行时,这将避免返回多个 NL
标记;除非空白行很重要,否则这可能就是您想要的。
第二种模式避免匹配任何换行符,因此它不会与第一种模式冲突。
有些人担心 Windows 行尾 (\r\n
) 的使用,但由于 Javascript 的 \s
包含 \r
,所以有这里没有真正的问题。 \r
将被第二条规则忽略,而 \n
将被第一条规则识别。如果您认为有必要,可以将第一个规则更改为 \r?\n\s*
以提高效率,但结果可能不会更快。
@rici 的回答很有帮助,它让我走上了正确的轨道。然而,[ \t]+
没有做我需要的。这些是我最终使用的两条线:
(\r?\n)+\s* return 'NEWLINE';
[^\S\r\n]+ ; /* whitespace */
我找到了它们 here。
编辑:@rici 更新后的答案比这个答案更清楚,并且完全符合我的需要,所以我接受了。
我有一段 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(); $$ = ; }
;
text
: TEXT
{ $$ = ; }
;
这是我目前输入的样子(我从我计划拥有的最基本的结构开始,我想从那里开始构建它):
[sectionA]
[sectionB]
[sectionC]
我遇到的问题是未检测到新行。它总是进入 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
将来这会变得更复杂一些,但我最初的想法是将其分解为每行(在许多情况下,新行将用作分隔符)。我对这些东西完全陌生,所以我可能对如何解决这个问题有一个完全错误的想法。所以我的问题是如何检测新行?此外,如果对我正在尝试做的事情有更好的方法,我们非常欢迎任何建议。谢谢。
这两个规则都将匹配换行符:
\s+ /* skip whitespace */
\n+ return 'NL';
既然先到先得,就赢了。 (Flex 会警告您未使用第二条规则,但我不相信 jison 会进行该分析。)
虽然改变规则的顺序没有帮助,因为第一条规则将匹配 SPACE NL ,从而吞下换行符(如果它前面有空格)。您需要更改空格规则以仅匹配不是换行符的空格。
一种可能性是:
\n\s* return 'NL';
[^\S\n]+ /* ignore whitespace other than newlines */
第一个模式将匹配换行符后跟任何空格序列,这意味着它将匹配多个换行符。当输入中有一个空行时,这将避免返回多个 NL
标记;除非空白行很重要,否则这可能就是您想要的。
第二种模式避免匹配任何换行符,因此它不会与第一种模式冲突。
有些人担心 Windows 行尾 (\r\n
) 的使用,但由于 Javascript 的 \s
包含 \r
,所以有这里没有真正的问题。 \r
将被第二条规则忽略,而 \n
将被第一条规则识别。如果您认为有必要,可以将第一个规则更改为 \r?\n\s*
以提高效率,但结果可能不会更快。
@rici 的回答很有帮助,它让我走上了正确的轨道。然而,[ \t]+
没有做我需要的。这些是我最终使用的两条线:
(\r?\n)+\s* return 'NEWLINE';
[^\S\r\n]+ ; /* whitespace */
我找到了它们 here。
编辑:@rici 更新后的答案比这个答案更清楚,并且完全符合我的需要,所以我接受了。