Yacc 是什么?
编译器的编译器。
简单来说,Yacc读入一套语法定义规格(syntax rules), 然后分析一段代码(source code), 判断代码是否符合定义好的syntax rules。
语法定义规格是由形式化的BNF表达式来定义;目前大多数语言都可以用它来定义。
一个BNF表达式由一个NONTERMINAL(非终结符)和它的产生式组成,产生式可以是终结符(TERMINAL)和非终结符组成的序列。比如,我们定义一个函数声明:
function_decl := function func_name ( argment_list );
func_name := id
argument_list := argument_list , id
argument_list := id
斜体字表示非终结符,而粗体的是终结符。
一套完整的BNF文法意味着每一个NONTERMINAL最终都可以推导为一系列的TERMINAL。
一套文法定义了什么样的语言?如上面的function_decl, 非形式化的来说,一个function_decl 开头是一个function关键字,然后紧接着一个func_name,也就是一个id,表示函数名字,然后是一个'(', 加上一个参数列表,再加上一个')'
参数列表是由','分隔的id列表。
例如:function foo (kick, so, by);
BNF或是扩展EBNF(扩展BNF)表达式有几下几种表达方式:
S := A B C (S 推导出A B C 三个部分)
S := A | B | C (S推导出A 或 B 或 C三个符号)
S := { A } (S推导出一个或多个A}
编译器的编译器。
简单来说,Yacc读入一套语法定义规格(syntax rules), 然后分析一段代码(source code), 判断代码是否符合定义好的syntax rules。
语法定义规格是由形式化的BNF表达式来定义;目前大多数语言都可以用它来定义。
一个BNF表达式由一个NONTERMINAL(非终结符)和它的产生式组成,产生式可以是终结符(TERMINAL)和非终结符组成的序列。比如,我们定义一个函数声明:
function_decl := function func_name ( argment_list );
func_name := id
argument_list := argument_list , id
argument_list := id
斜体字表示非终结符,而粗体的是终结符。
一套完整的BNF文法意味着每一个NONTERMINAL最终都可以推导为一系列的TERMINAL。
一套文法定义了什么样的语言?如上面的function_decl, 非形式化的来说,一个function_decl 开头是一个function关键字,然后紧接着一个func_name,也就是一个id,表示函数名字,然后是一个'(', 加上一个参数列表,再加上一个')'
参数列表是由','分隔的id列表。
例如:function foo (kick, so, by);
BNF或是扩展EBNF(扩展BNF)表达式有几下几种表达方式:
S := A B C (S 推导出A B C 三个部分)
S := A | B | C (S推导出A 或 B 或 C三个符号)
S := { A } (S推导出一个或多个A}