为什么像 `(!"foo" .*)` 这样的表达式会在 PEG.js 中生成 `[undefined, char]` 值的数组
Why does an expression like `(!"foo" .*)` generate arrays of `[undefined, char]`-values in PEG.js
我对PEG.js还是很陌生,我猜这只是初学者的误解。
试图解析这样的东西:
definitions
some text
if
some additonal text
to parse here
then
still more text will
go here
我可以获得正确阅读这三个部分的语法(当然,稍后会进一步解析。)但它会以一种奇怪的格式生成该文本。例如,在上面,“some text”变成了
[
[undefined, "s"], [undefined, "o"], [undefined, "m"], [undefined, "e"], [undefined, " "],
[undefined, "t"], [undefined, "e"], [undefined, "x"], [undefined, "t"]
]
我可以很容易地将其转换为纯字符串,但我想知道我正在做些什么来赋予它这种糟糕的格式。到目前为止,这是我的语法:
{
const combine = (xs) => xs .map (x => x[1]) .join('')
}
MainObject
= _ defs:DefSection _ condition:CondSection _ consequent: ConsequentSection
{return {defs, condition, consequent}}
DefSection = _ "definitions"i _ defs:(!"\nif" .)+
{return defs}
CondSection = _ "if"i _ cond:(!"\nthen" .)+
{return combine (cond)}
ConsequentSection = _ "then"i _ cons:.*
{return cons .join ('')}
_ "whitespace"
= [ \t\n\r]*
我可以通过将 {return defs}
替换为 {return combine(defs)}
来修复它,就像在其他部分中一样。
我的主要问题很简单,它为什么会生成该输出?有没有更简单的方法来修复它?
总的来说,因为我对 PEG.js 还是很陌生,我很想知道是否有更好的方法来编写这个语法。 (!"\nif" .*)
之类的表达式似乎很粗略。
- 负面展望,例如
!Rule
,将始终 return 未定义,如果 Rule
匹配,将失败。
- 点
.
将始终匹配单个字符。
- 一个序列
Rule1 Rule2 ...
将创建一个包含每个规则 结果的列表
- 重复
Rule+
或 Rule*
将匹配 Rule
尽可能多的次数并创建一个列表。 (如果第一次尝试匹配规则失败,+
失败)
你的成绩是
[ // Start (!"\nif" .)
[undefined // First "\nif",
"s" // First .
] // first ("\nif" .)
,
[undefined, "o"] // Second (!"\nif" .)
, [undefined, "m"], [undefined, "e"], [undefined, " "],
[undefined, "t"], [undefined, "e"], [undefined, "x"], [undefined, "t"]
] // This list is (!"\nif" .)*, all the matches of ("\nif" .)
您似乎想要的是阅读文本,您可以为此使用运算符 $Rule
,它将 return 输入而不是生成的输出。
MainObject
= _ defs:DefSection _ condition:CondSection _ consequent: ConsequentSection
{return {defs, condition, consequent}}
DefSection = _ "definitions"i _ defs:$(!"\nif" .)+
{return defs.trim()}
CondSection = _ "if"i _ cond:$(!"\nthen" .)+
{return cond.trim()}
ConsequentSection = _ "then"i _ cons:$(.*)
{return cons.trim()}
_ "whitespace"
= [ \t\n\r]*
会产生
{
"defs": "some text",
"condition": "some additonal text
to parse here",
"consequent": "still more text will
go here"
}
我对PEG.js还是很陌生,我猜这只是初学者的误解。
试图解析这样的东西:
definitions
some text
if
some additonal text
to parse here
then
still more text will
go here
我可以获得正确阅读这三个部分的语法(当然,稍后会进一步解析。)但它会以一种奇怪的格式生成该文本。例如,在上面,“some text”变成了
[
[undefined, "s"], [undefined, "o"], [undefined, "m"], [undefined, "e"], [undefined, " "],
[undefined, "t"], [undefined, "e"], [undefined, "x"], [undefined, "t"]
]
我可以很容易地将其转换为纯字符串,但我想知道我正在做些什么来赋予它这种糟糕的格式。到目前为止,这是我的语法:
{
const combine = (xs) => xs .map (x => x[1]) .join('')
}
MainObject
= _ defs:DefSection _ condition:CondSection _ consequent: ConsequentSection
{return {defs, condition, consequent}}
DefSection = _ "definitions"i _ defs:(!"\nif" .)+
{return defs}
CondSection = _ "if"i _ cond:(!"\nthen" .)+
{return combine (cond)}
ConsequentSection = _ "then"i _ cons:.*
{return cons .join ('')}
_ "whitespace"
= [ \t\n\r]*
我可以通过将 {return defs}
替换为 {return combine(defs)}
来修复它,就像在其他部分中一样。
我的主要问题很简单,它为什么会生成该输出?有没有更简单的方法来修复它?
总的来说,因为我对 PEG.js 还是很陌生,我很想知道是否有更好的方法来编写这个语法。 (!"\nif" .*)
之类的表达式似乎很粗略。
- 负面展望,例如
!Rule
,将始终 return 未定义,如果Rule
匹配,将失败。 - 点
.
将始终匹配单个字符。 - 一个序列
Rule1 Rule2 ...
将创建一个包含每个规则 结果的列表
- 重复
Rule+
或Rule*
将匹配Rule
尽可能多的次数并创建一个列表。 (如果第一次尝试匹配规则失败,+
失败)
你的成绩是
[ // Start (!"\nif" .)
[undefined // First "\nif",
"s" // First .
] // first ("\nif" .)
,
[undefined, "o"] // Second (!"\nif" .)
, [undefined, "m"], [undefined, "e"], [undefined, " "],
[undefined, "t"], [undefined, "e"], [undefined, "x"], [undefined, "t"]
] // This list is (!"\nif" .)*, all the matches of ("\nif" .)
您似乎想要的是阅读文本,您可以为此使用运算符 $Rule
,它将 return 输入而不是生成的输出。
MainObject
= _ defs:DefSection _ condition:CondSection _ consequent: ConsequentSection
{return {defs, condition, consequent}}
DefSection = _ "definitions"i _ defs:$(!"\nif" .)+
{return defs.trim()}
CondSection = _ "if"i _ cond:$(!"\nthen" .)+
{return cond.trim()}
ConsequentSection = _ "then"i _ cons:$(.*)
{return cons.trim()}
_ "whitespace"
= [ \t\n\r]*
会产生
{
"defs": "some text",
"condition": "some additonal text
to parse here",
"consequent": "still more text will
go here"
}