解析“简单”语法

2024-10-04 01:24:36 发布

您现在位置:Python中文网/ 问答频道 /正文

提前抱歉;我相信这个问题对于那些习惯于使用解析器和语法的人来说几乎是白痴,但是这些对我来说都是陌生的话题,这是我试图温和地步入一个需要它们的实际案例。在

我想为以下“语言”编写一个解析器,它包含一个“特殊结构”,如下所示:

\command[ options ]{ contents }

内容可以是任何内容,包括嵌套命令,并且可以包含转义方括号或反斜杠\{ \} \\。我意识到“任何东西”都不是具体的,但如果可能的话,它们应该由匹配的括号(不包括转义的)来确定。在

选项应该是一个逗号分隔的赋值表达式列表,例如name = value,但是值可以是一个包含=,字符的带引号的字符串。最后,前面的name和{}应该验证正则表达式\w[\w\d\._-+*]*——也就是说,第一个字符应该是字母,其余字符应该是字母、数字或. _ - + *中的一个。在

用正则表达式编写这个似乎过于复杂(例如,因为值可能包含引号字符, =,否则将分隔赋值或名称/值对)。因此,我认为这里最合适的工具是语法,但是尽管读了一些肤浅的东西,我还是不知道怎么写它(BNF、PEG等等?),使用哪种类型的解析器(LR、recursive decept等?),以及如何在实际程序中使用解析输出。在

我更喜欢用Python来回答,Python解释了标记,但是如果需要/更适合,我当然会非常乐意使用工具组合。在


注意:这与乳胶无关。当然,我意识到了相似性,但是LaTeX比以前的语言要复杂得多,例如字符代码随上下文而变化。我只是想问一个实际的例子,这个例子(我认为)足够简单,而且在我的日常工作中已经对我有用了。在


Tags: 工具name语言解析器内容字母语法字符
1条回答
网友
1楼 · 发布于 2024-10-04 01:24:36

从更正式地表达你的语法开始,用你喜欢的任何符号。e、 g.根据您的描述,EBNF应该是这样的:

program := element+
element := command | literal
literal := (not '\')+

command := '\'identifier options? '{' program '}'
options := option | options ',' option
option  := identifier '=' value
value   := number | string

string  := '"' (escape | not '\' or '"')* '"'
escape  : = '\' char

然后将其输入到解析器生成器(pyParsing、pyYACC、ANTLR)或手动编写解析器。在后一种情况下,自上而下是最简单的选择:从语法的顶部开始,将每个规则转换为一个函数,该函数将返回已解析的AST节点并使用输入,或者不返回任何内容或抛出。示例:

^{pr2}$

其中next_sym返回来自输入的下一个符号(或EOF上的None),而get_sym使用该符号并推进输入缓冲区。在

相关问题 更多 >