我试图更深入地理解Python的工作原理,我一直在研究http://docs.python.org/3.3/reference/grammar.html处显示的语法.

我注意到它说您必须更改parsermodule.c也是,但说实话,我只是不明白这里发生了什么.

我知道语法是如何阅读语言的规范,但是...我都说不清这是怎么写的.它看起来几乎像Python,但事实并非如此.

我希望更好地理解这个规范,以及Python如何在内部使用它来....做事.什么取决于它(答案是一切,但我的具体意思是"引擎"的哪个方面在处理它)、它的用途、它如何与编译/运行脚本相关联?

很难相信整个语言归结为一个两页的规范...

推荐答案

语法用于描述语言中所有可能的字符串.它在指定解析器应该如何解析语言时也很有用.

在这种语法中,他们似乎在使用自己版本的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

我们可以使用以下推导:

  1. 单输入
  2. 复合新线
  3. 如果新线
  4. 'if'test':'suite NEWLINE
  5. "如果"或"测试":"换行符缩进stmt stmt DEDENT换行符"
  6. "如果"和"_测试"或"和"_测试":"换行缩进简单换行"
  7. 'if'not_test'或'not_test':'NEWLINE INDENT small_stmt DEDENT NEWLINE
  8. '如果'comparison'或'not'not_test':'换行符缩进流\u stmt DEDENT换行符
  9. '如果'expr comp_op expr'或'not'comparison':'换行缩进上升\u stmt DEDENT换行
  10. '如果'arith_expr'<;'arith_expr'或'not'arith_expr comp_op arith_expr':'NEWLINE INDENT'raise'DEDENT NEWLINE
  11. '如果'term'<;'术语"+"术语"或"非"arith_expr==arith_expr":"换行缩进"提升"DEDENT换行"
  12. '如果'NUMBER'<;'数字"+"数字"+"或"非"数字==NUMBER":"换行缩进"换行

这里有几个注意事项,首先,我们必须从一个非终端开始,它被列为起始非终端.在该页面中,他们将其列为单输入、文件输入或判断输入.第二,一旦所有符号都是终端符号(因此得名),派生就完成了.第三,更常见的是每行做一次替换,为了简洁起见,我一次做了所有可能的替换,并开始跳过接近结尾的步骤.

给定语言中的一个字符串,我们如何找到它的派生词?这是解析器的工作.解析器对生产序列进行反向工程,首先判断它是否确实是有效字符串,以及如何从语法中派生它.值得注意的是,许多语法可以描述一种语言.然而,对于一个给定的字符串,它的派生对于每种语法来说当然是不同的.所以从技术上讲,我们为语法而不是语言编写解析器.有些语法更容易解析,有些语法更容易阅读/理解.这个属于前者.

此外,这并没有指定整个语言,只是它的外观.语法与语义无关.

如果你对解析和语法感兴趣,我推荐Grune, Jacobs - Parsing Techniques个.这是免费的,适合自学.

Python-3.x相关问答推荐

Python gpsd客户端

S的两极是什么,相当于大Pandas 的`.ilo‘方法?

为什么在Python中使用RANDINT函数时会出现此TypeError?

为什么 tkinter 在 tkinter 窗口外计算鼠标事件?

我可以设置树视图层次 struct 按钮吗?

Python3:是否可以将变量用作函数调用的一部分

如果原始字符串包含正斜杠,如何返回具有不同可能性的新字符串

在python中将字符串写入文本文件

如何使用 regex sub 根据列表中的变量替换字符

spaCy 中的匹配模式返回空结果

Pandas 值列中列表中元素的计数

ImportError:无法从jinja2导入名称escape

将名字转换成姓氏、首字母和中间字母的格式

python用户输入5个偶数并打印最大的

具有 2 个输入的 python 3 map/lambda 方法

ValueError:FixedLocator 位置的数量 (5),通常来自对 set_ticks 的调用,与刻度标签的数量 (12) 不匹配

为 True 相交两个布尔数组

为 Python 3 和 PyQt 构建可执行文件

异常被忽略是什么类型的消息?

有没有办法在多个线程中使用 asyncio.Queue ?