好的,我有一个练习来构建一种java编译器。我不会在细节上得到太多。 基本上,我想知道是否可以使用可以识别结束括号的正则表达式。 例如,这将是一个合法的输入
void foo(){
asd
}
这不会是
void foo(){
asd
if (){
asd
}
正如您所看到的,2个开头({)只有1个close(}),使其无效输入。有没有办法使用正则表达式并确定出现次数匹配?
答案 0 :(得分:5)
无法使用正则表达式检查正确的括号,因为要检查是否需要跟踪已打开的括号数等,但正则表达式无法执行此操作。
我建议你,特别是如果你想构建一个编译器,熟悉形式语言理论。例如,这篇维基百科文章提供了对形式语言理论背景中正则表达式的一些见解:http://en.wikipedia.org/wiki/Regular_expression#Formal_language_theory
答案 1 :(得分:1)
最简单(简化?)答案:
如果解析语法,通常会直接或间接维护某种堆栈。对于每个左括号,都会将元素推送到堆栈。看到结束括号后,通过检查堆栈,您知道它是否与最后一个开启括号匹配。
另请注意,打开括号有很多方法,“{”只是其中之一。 因此,堆栈不仅告诉您在给定的解析状态下有多少个开括号,还有哪种类型的右括号。
答案 2 :(得分:1)
标准正则表达式只能表达regular languages的语法,这正是deterministic finite automata接受的语言类。 DFA只有有限数字状态,而括号可以无限期嵌套;一种可能具有无限级别嵌套的语言不是常规语言,不能仅通过正则表达式进行解析。
虽然大多数语言中的正则表达式库不是“只是”标准的正则表达式,并且能够解析一些非常规语言,但它们通常需要过于复杂的表达式。
通常,要检查格式良好的括号语言嵌套,您需要一个context-free grammar(CFG)解析器。 CFG严格强于正则表达式(即如果一个语法可以用RE表示,那么它可以在CFG中表达,反之则不一定正确。)
答案 3 :(得分:0)
如果你使用C
,那么好的工具就是Flex for Tokens和Bison的语法JFlex和Cup,如果你想用Java做,也使用访问者模式来获得更好的程序结构