Parsing Peg解析器-支持转义字符
我正在做一个Peg解析器。在其他结构中,它需要解析标记指令。标记可以包含任何字符。如果希望标记包含大括号Parsing Peg解析器-支持转义字符,parsing,escaping,peg,pegjs,Parsing,Escaping,Peg,Pegjs,我正在做一个Peg解析器。在其他结构中,它需要解析标记指令。标记可以包含任何字符。如果希望标记包含大括号},可以使用反斜杠将其转义。如果你需要一个反斜杠,也应该转义。受JSON的Peg语法启发,我尝试实现这一点: 有两个问题: 转义反斜杠将导致两个反斜杠字符,而不是一个。输入示例: 解析器在转义的卷曲上中断\}。输入示例: 相关语法为: Tag = "{" _ tagContent:$(TagChar+) _ "}" { return {
}
,可以使用反斜杠将其转义。如果你需要一个反斜杠,也应该转义。受JSON的Peg语法启发,我尝试实现这一点:
有两个问题:
- 转义反斜杠将导致两个反斜杠字符,而不是一个。输入示例:
- 解析器在转义的卷曲上中断
。输入示例:\}
Tag
= "{" _ tagContent:$(TagChar+) _ "}" {
return { type: "tag", content: tagContent }
}
TagChar
= [^\}\r\n]
/ Escape
sequence:(
"\\" { return {type: "char", char: "\\"}; }
/ "}" { return {type: "char", char: "\x7d"}; }
)
{ return sequence; }
_ "whitespace"
= [ \t\n\r]*
Escape
= "\\"
您可以使用在线PegJS沙盒轻松测试语法和输入:
我希望有人有办法解决这个问题。这些错误基本上都是打字错误 第一个问题是正则表达式中用于标记字符的字符类。在字符类中,
\
仍然是转义字符,因此[^\}\r\n]
匹配除}
(使用不必要的反斜杠转义)、回车符或换行符以外的任何字符\
就是这样一个字符,因此它由character类匹配,Escape
从未尝试过
由于标记字符的模式无法成功地将\
识别为转义
,因此标记{\\}
被解析为四个字符(空格、反斜杠、反斜杠、空格),标记{\}
被解析为在第一个}
终止,从而产生语法错误
因此,您应该将字符类修改为[^}\\\\r\n]
(我将右括号放在第一位,以便更容易阅读掉落的木材。顺序与此无关。)
一旦您这样做了,您会发现解析器仍然返回带有反斜杠的字符串。这是因为标记中的$
模式:“{”\tagContent:$(TagChar+)}”
。根据,$
运算符的含义是:(强调添加)
$expression
尝试匹配表达式。如果匹配成功,返回匹配的文本而不是匹配结果。
为了便于参考,正确的语法如下:
Tag
= "{" _ tagContent:TagChar+ _ "}" {
return { type: "tag", content: tagContent.map(c => c.char || c).join('') }
}
TagChar
= [^}\\\r\n]
/ Escape
sequence:(
"\\" { return {type: "char", char: "\\"}; }
/ "}" { return {type: "char", char: "\x7d"}; }
)
{ return sequence; }
_ "whitespace"
= [ \t\n\r]*
Escape
= "\\"
使用以下输入时:
{ some characters but escape \} with a \\ }
它将返回:
{
"type": "tag",
"content": "some characters but escape } with a \ "
}
{ some characters but escape \} with a \\ }
{
"type": "tag",
"content": "some characters but escape } with a \ "
}