我正在观看有关使用正则表达式为词法分析器(词法分析器)定义语法的编译器的课程,该词汇分析器使用此正则表达式来配置有限自动机。只有当课程进入语法分析器(解析器)部分时,才会引入特定于无上下文语法的术语,如产品,终端和非终端。由此得出结论,这些仅在语法分析期间使用。
然而,词法分析器的EcmaScript规范defines productions:
词法和RegExp语法的制作区别在于 有两个冒号“::”作为分隔标点符号。词汇和 RegExp语法共享一些产品。
词法分析器的语法也可以使用具有终端和非终端符号的产品而不仅仅是regexp来指定吗?
This grammar tutorial还提到无语境语法(CFG)是普通语法的超集,所以似乎我的问题的答案是"是"。我很欣赏一点解释。提前致谢
答案 0 :(得分:4)
这已经在评论中得到了回答,但除非它是重复的,否则它应该得到答案。
在您自己的链接中,是的,任何处理无上下文语法的解析器也可以处理常规语法。无上下文语法是由下推自动机(PDA)识别的语法,它是由有限状态机(FSM)识别的严格超集 1 。例如,here有一个很好的章节。
(请注意常规语言,我将调用" RL"此处虽然不是常见的缩写,但是可以被FSM识别的语言。上下文无关语言或CFL是可以被PDA识别的语言。同时,常规语法或RG是识别常规语言和语境的语言 - 自由语法或CFG是一种识别无上下文语言的语法.CFL,CFG,PDA和FSM都是通用和标准的缩写;它是我在这里使用的RL和RG缩写,而不是。我们也有RE或RE,代表正则表达式,这就是我们编写常规语言 -our RL的方式 - 我们用它来构建识别这个RL中的"单词"的FSM。 )
我们通常想出一些RL并为此编写一个基于正则表达式的小型FSM识别器以将输入转换为标记,然后使用无上下文语法解析标记,这是因为它使得更小,更简单代码构造。不进行大量优化的编译器倾向于将大部分时间花在令牌化代码上(尽管这显然因语言而异:例如,某些语言具有复杂的类型系统,可能导致他们花费大部分时间来进行类型匹配)所以,只要我们能够做到这一点小而快,我们就会前进。
作为Bergi notes,您在ECMAScript中查看的具体问题是语法,源语言通过该语法表达正则表达式。 (那个句子太复杂了吗?:-))虽然正则表达式可以被 FSM(而不是PDA)识别,但我们用来写正则表达式本身不需要是RL-并且在ECMAScript中,它不是。
事实上,使用RL和CFL的混合来编码RE是非常典型的。例如,在C,C ++和Python中,RE处理在库中,我们向库例程发送一个字符串,它将编译"进入一些FSM。字符串本身在CFL中对RE进行编码,因此(运行时)编译到FSM中可能会失败。其他一些语言,例如awk,将RE语法提升到语法中,但提出了一个周围的常规语言来表达它 - 例如/ pattern /,模式中有任何嵌入的斜杠编码为\/
。通过在RL中对RE进行编码,这些语言允许其基于FSM的标记生成器将整个RE转换为单个标记,而不使用CFG。然后可以在编译时而不是运行时编译令牌(使用将令牌再次分开的单独子例程),并且可以在awk"编译"生成任何编译时语法冲突。时间(无论如何都是运行时间)。
ECMAScript只是选择与众不同。它的RE语言不是RL,而是CFL,因此只有PDA而不是FSM才能识别它。无论是否能以类似awk的方式处理,我都不确定:CFL部分是在第21.2.1节中定义的,并且在第11.8.5节中有一个周围的RL。作为Bergi notes again,嵌入式CFL需要PDA / CFG(例如,21.2.1中的语法具有平衡括号:析取嵌入了额外的析取,并且之后需要右括号)。
(哇!太多的TLA! 2 :-))
1 这种严格的超集意味着有许多CFM无法被FSM识别。一个典型的例子是FSM不能平衡任意数量的括号,而PDA则可以。如果您选择一些上限,例如"不超过100个嵌套括号",您可以生成一个(相当惊人的大)FSM,它可以识别所有不超过100个嵌套括号的输入,但仍然具有平衡括号中。
2 TLA:三个(或偶尔两个)字母缩写。另见ETLA,扩展三字母缩写。