regex是否应该在解析器或编译器的解析器中使用?

时间:2017-06-14 23:12:28

标签: regex parsing

在解析语法时,是否应该使用RegEx来匹配可以表示为常规语言的语法,还是应该专门使用当前的解析器设计?

例如,JSON的EBNF语法可表示为:

object ::= '{' '}' | '{' members '}';
members ::= pair | pair ',' members;
pair ::= string ':' value;
array ::= '[' ']' | '[' elements ']';
elements ::= value | value ',' elements;
value ::= string | number | object | array | 'true' | 'false' | 'null';

因此需要使用某种类型的词法分析器(例如递归下降解析器或ad hoc解析器)来匹配语法,但是某些值(例如数字)的语法可以表示为常规语言喜欢这个RegEx模式的数字:

-?\d+(\.\d+)?([eE][+-]?\d+)?

给出这个例子,假设一个人正在创建递归下降JSON解析器...应该通过递归下降技术匹配数字还是应该通过RegEx匹配数字,因为它可以使用RegEx轻松匹配?

1 个答案:

答案 0 :(得分:1)

这是一个非常广泛和自以为是的问题。因此,据我所知,通常你会希望解析器尽可能快,并尽可能在内存中占用最少的空间,特别是如果它需要实时解析(按需)。

RegEx肯定会完成这项工作,但就像用核武器射击一样!

这就是为什么许多解析器都是用C语言等低级语言编写的,以利用字符串指针,避免由不可变字段,垃圾收集器等Java等高级语言引起的开销......

同时,这在很大程度上取决于您的使用案例,并且无法以通用方式真正回答。您应该考虑开发人员使用RegEx的方便性与解析器的性能之间的权衡。

一个额外的考虑因素通常是您希望解析器指出您有语法错误的位置,以及它是哪种类型的错误。使用RegEx,它将无法匹配,您将很难找到它停止的原因,以显示正确的错误消息。使用旧式解析器时,只要遇到语法错误就可以快速停止解析,并且可以准确地知道哪些不匹配以及在哪里。

在你的JSON解析和仅对数字使用RegEx的特定情况下,我想你可能已经使用了高级语言,所以许多实现的工作依赖于语言对数字的本机解析。所以只需使用分隔符选择值(字符串,数字......),让编程语言为数字解析抛出异常。