当前位置: 首页 > 面试题库 >

Python语法在内部如何使用?

韩淇
2023-03-14
问题内容

我试图更深入地了解Python的工作方式,并且一直在查看http://docs.python.org/3.3/reference/grammar.html上显示的语法。

我注意到它说您也必须更改parsermodule.c,但说实话,我只是不关注这里发生的事情。

我了解语法是如何阅读该语言的规范,但是…我什至不知道该写的是什么。它看起来几乎像Python,但实际上不是。

我希望更好地了解此规范以及Python在内部如何使用它来做某事。取决于什么(答案是一切,但我具体是指“引擎”的哪个方面正在处理它),使用它的方式以及它如何与编译/运行脚本联系在一起?

很难相信整个语言可以归结为两页的规范…


问题答案:

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

在此语法中,似乎他们使用的是自己的EBNF版本,其中非终止符是任何小写单词,而终止符则全部是大写字母或用引号引起来。例如,NEWLINE是终端,arith_expr是非终端,而’if’也是终端。任何非终结符都可以由其相应生产规则的冒号右侧的任何内容替换。例如,如果您查看第一个规则:

single_input:NEWLINE | simple_stmt | compound_stmt NEWLINE

我们可以用newLINE,simple_stmt或compound_stmt后跟NEWLINE之一替换single_input。假设我们将其替换为“
compound_stmt NEWLINE”,那么我们将寻找compound_stmt的生产规则:

compound_stmt:if_stmt | while_stmt | for_stmt | try_stmt | with_stmt |
funcdef | classdef | 装饰的

并选择我们要使用的其中一个,然后将其替换为“ compound_stmt”(将NEWLINE保留在此处)

假设我们要生成有效的python程序:

if 5 < 2 + 3 or not 1 == 5:
    raise

我们可以使用以下推导:

  1. 单输入
  2. compound_stmt NEWLINE
  3. if_stmt NEWLINE
  4. ‘if’test’:’套件NEWLINE
  5. ‘if’or_test’:’NEWLINE INDENT stmt stmt DEDENT NEWLINE
  6. ‘if’and_test’or’and_test’:’NEWLINE INDENT simple_stmt DEDENT NEWLINE
  7. ‘如果’not_test’或’not_test’:’NEWLINE INDENT small_stmt DEDENT NEWLINE
  8. ‘如果’比较’或’‘不是’not_test’:’NEWLINE INDENT flow_stmt DEDENT NEWLINE
  9. ‘if’expr comp_op expr’或’‘not’比较’:’‘NEWLINE INDENT raise_stmt DEDENT NEWLINE
  10. ‘if’arith_expr’<’arith_expr’或’‘not’arith_expr comp_op arith_expr’:’NEWLINE INDENT’raise’DEDENT NEWLINE
  11. ‘if’词’<’词’+’词’或’‘not’arith_expr == arith_expr’:’NEWLINE INDENT’raise’DEDENT NEWLINE
  12. ‘if’NUMBER’<’NUMBER’+’NUMBER’or’‘not’NUMBER == NUM​​BER’:’NEWLINE INDENT’raise’DEDENT NEWLINE

首先,在这里有两个注意事项,我们必须从列出为起始非终端的非终端之一开始。在该页面中,他们将它们列出为single_input,file_input或eval_input。其次,一旦所有符号都终止了,派生就完成了(因此得名)。第三,更常见的做法是每行进行一次替换,为简洁起见,我立即进行了所有可能的替换,并开始在结尾处跳过步骤。

给定语言字符串,我们如何找到它的派生?这是解析器的工作。解析器对生产序列进行逆向工程,以首先检查它是否确实是有效字符串,然后再检查如何从语法中得出该字符串。值得注意的是,许多语法可以描述一种语言。但是,对于给定的字符串,每个语法的推导当然会有所不同。因此,从技术上讲,我们为语法而不是语言编写解析器。一些语法更易于解析,一些语法更易于阅读/理解。这个属于前者。

同样,这并没有指定整个语言,而是它的外观。语法对语义一无所知。

如果您对解析和语法有更多的兴趣,我建议使用Grune,Jacobs-
解析技术
。它是免费的,适合自学。



 类似资料:
  • 问题内容: Unicode字符串如何在Python的内存中按字面表示? 例如,我可以在内存中可视化为等效的ASCII字节。整数可以认为是2的恭维表示形式。但是,即使以3个字节长表示,我如何在内存中可视化原义代码点? 是否有将其存储在内存中的特定方法?Python 2和Python 3是否有区别? 问题答案: 我假设您想了解CPython(标准实现)。Python 2和Python 3.0-3.2对

  • 语法到底有什么问题,为什么会出现在下面的代码中?我已经数过括号了,但还没弄清楚。 注意:它给出了如下语法错误:

  • 我正在尝试使antlr C#g4语法与Python3中的antlr运行时一起工作。 下载文件夹中的antlr jar 同时在文件夹中下载lexer和解析器语法 通过对antlr JAR的java调用生成lexer和parser类 获取相关的类,这是lexer部分失败的事情,我将回到下面的错误 肮脏的代码 这段代码除了两件事外还可以工作: 首先,我发现了一些错误,这些错误似乎实际上是警告(请参阅Gi

  • 问题内容: 我一直在寻找是否有某种方法可以使用中的类,但我还没有找到任何文档或有关此主题的指南。 假设我创建了一个简单的类,其中使用的一些库,例如: 有没有可能在此类中使用此类? 太难了吗? 我必须创建一个文件吗? 有没有指导说明如何做到这一点? 顺便说一句,我也看了一下代码,感到有点迷茫,我无法出于自己的目的复制它们的功能。 问题答案: 是的,尽管不是很琐碎,但它是可能的。通常,您需要一个Jav

  • 问题内容: 我尝试了解如何使用“内部”包组织代码。让我展示一下我的结构: 在GOPATH树之外。无论我尝试从什么都不导入的任何路径都可行,唯一可行的情况是。我认为我做错了什么,或者总体上弄错了“内部”包装想法。任何人都可以让事情变得更清楚吗? 更新 上面的示例是正确的,我唯一需要的是将文件夹放在下。因此,如果我们仅从子树而不是从外部导入,则该导入路径是可行的。 问题答案: 包必须位于您的包中才能导

  • 问题内容: 我正在尝试装饰类中的方法,但是python抛出错误。我的课看起来像这样: : Python抛出以下错误 我要去哪里玩? 问题答案: Python自动将类实例作为参考传递。(在所有类方法中都可以看到的参数)。 您可以这样做: