8fbbfc2e05db997472e9c3e51214e2f8
Python的语法分析(二)

Python的语法分析(二)

上文我们讲述了4种文法的定义和对应的限制,并大致浏览了Python语法的文法定义(如下节选),今天就让我们一起来探究一下,这些文法定义是如何得出的。

atom_expr: ['await'] atom trailer*
atom: ('(' [yield_expr|testlist_comp] ')' |
       '[' [testlist_comp] ']' |
       '{' [dictorsetmaker] '}' |
       NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False')
testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )

表达式

Python中,语句的表达式多种多样,可能存在如下几种形式:

  • a
  • a > 5
  • print "a > 5"
  • if a > 5: print "a > 5"
  • while a > 5: print a
  • for a in range(5, 10): print a

忽略换行缩进

对于上述这些,如果我们将其中具体数值和变量定义泛化,以EXPR来表征表达式的话,可以得到如下内容:

  • 0: EXPR = NAME(词法分析的结果ID)
  • 1: EXPRT = NAME STRING(a > 5)
  • 2: EXPR = NAME GREATER NUMBER(5)
  • 3: EXPR = KEYWORD(if) NAME GREATER NUMBER(5) COLON NAME STRING(a > 5)
  • 4: EXPR = KEYWORD(while) ID GREATER NUMBER(5) COLON NAME NAME
  • 5: EXPR = KEYWORD(for) NAME KEYWORD(in) NAME LPAR Number(5) COMMA Number(10) COLON NAME NAME

上述的括号不是词法分析的结果,是我为了展现内容做的。

看起来好复杂,EXPR表征的语句特别复杂,这还是我们例子比较简单的情况下。因此,我们需要从上述的各个EXPR寻找公共的特征,进行提取,来简化我们的文法定义。

我们先来看如下两行式子:

  • 2: EXPR = NAME GREATER NUMBER(5)
  • 3: EXPR = KEYWORD(if) NAME GREATER NUMBER(5) COLON NAME STRING(a > 5)

其中是不是有公共的NAME GREATER NUMBER(5),那说明我们的第二行式子的部分内容完全也是个合法的EXPR,赶紧将其简化,得到:

  • 3: EXPR = KEYWORD(if) EXPR COLON NAME STRING(a > 5)

那我们是不是还能继续简化呢?没错,将我们新得到的3式子继续和原来的1式进行合并,可以大幅简化成

  • 3: EXPR = KEYWORD(if) EXPR COLON EXPR

得到的这个式子可以表达一个什么含义呢?

递归

递归

top Created with Sketch.