语法用于描述语言中所有可能的字符串.它在指定解析器应该如何解析语言时也很有用.
在这种语法中,他们似乎在使用自己版本的EBNF,其中非终结符是任何小写单词,终结符都是大写或被引号包围.例如,换行符是一个终端,arith_expr是一个非终端,"if"也是一个终端.任何非终结符都可以替换为其各自产生式规则冒号右侧的任何内容.例如,如果你看第一条规则:
单输入:换行|简单|复合|换行
我们可以用换行符、简单换行符或后跟换行符的复合换行符中的一种来替换单输入.假设我们将其替换为"composite_stmt NEWLINE",那么我们将查找composite_stmt的生成规则:
复合material :如果material |而|material |用于|material |try |material |带有|功能定义|类别定义|装饰
t.我们要用哪种化合物来代替"新的"
假设我们想要生成有效的python程序:
if 5 < 2 + 3 or not 1 == 5:
raise
我们可以使用以下推导:
- 单输入
- 复合新线
- 如果新线
- 'if'test':'suite NEWLINE
- "如果"或"测试":"换行符缩进stmt stmt DEDENT换行符"
- "如果"和"_测试"或"和"_测试":"换行缩进简单换行"
- 'if'not_test'或'not_test':'NEWLINE INDENT small_stmt DEDENT NEWLINE
- '如果'comparison'或'not'not_test':'换行符缩进流\u stmt DEDENT换行符
- '如果'expr comp_op expr'或'not'comparison':'换行缩进上升\u stmt DEDENT换行
- '如果'arith_expr'<;'arith_expr'或'not'arith_expr comp_op arith_expr':'NEWLINE INDENT'raise'DEDENT NEWLINE
- '如果'term'<;'术语"+"术语"或"非"arith_expr==arith_expr":"换行缩进"提升"DEDENT换行"
- '如果'NUMBER'<;'数字"+"数字"+"或"非"数字==NUMBER":"换行缩进"换行
这里有几个注意事项,首先,我们必须从一个非终端开始,它被列为起始非终端.在该页面中,他们将其列为单输入、文件输入或判断输入.第二,一旦所有符号都是终端符号(因此得名),派生就完成了.第三,更常见的是每行做一次替换,为了简洁起见,我一次做了所有可能的替换,并开始跳过接近结尾的步骤.
给定语言中的一个字符串,我们如何找到它的派生词?这是解析器的工作.解析器对生产序列进行反向工程,首先判断它是否确实是有效字符串,以及如何从语法中派生它.值得注意的是,许多语法可以描述一种语言.然而,对于一个给定的字符串,它的派生对于每种语法来说当然是不同的.所以从技术上讲,我们为语法而不是语言编写解析器.有些语法更容易解析,有些语法更容易阅读/理解.这个属于前者.
此外,这并没有指定整个语言,只是它的外观.语法与语义无关.
如果你对解析和语法感兴趣,我推荐Grune, Jacobs - Parsing Techniques个.这是免费的,适合自学.