欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Python 之父的解析器系列之六:給 PEG 語法添加動作

系統 1788 0

? Python貓 ” ,一個值得加星標的 公眾號

花下貓語: Guido 的解析器系列更新了 7 篇,他的生產力真旺盛啊。這對于新的解析器來說是件好事,但對于我來說卻是個不小的挑戰:需要一定的時間和精力,而我對解析器的知識極為欠缺,也造成了翻譯過程的不順暢。

現在,我把譯文提到 Github 上了( guido_blog_translation ),希望有熱心腸的同學能來幫忙審閱指正,或者認領翻譯任務吧。最后,提前祝大家中秋節快樂,闔家團圓,諸事和美。

原題 | Adding Actions to a PEG Grammar
作者 | Guido van Rossum(Python之父)
譯者 | 豌豆花下貓(“Python貓”公眾號作者)
聲明 | 本翻譯是出于交流學習的目的,基于 CC BY-NC-SA 4.0 授權協議。 為便于閱讀,內容略有改動。

如果你在語法規則中還可以添加(某些)語義,那么語法就會更好。特別是對于我正在構建的 Python 解析器,我需要控制每個備選項返回的 AST 節點,因為 AST 的格式已經規定好。

【這是我的 PEG 系列的第 6 部分。其余部分請參閱系列概述】 (譯注: 本系列的譯文已在 Github 開源,項目地址: https://github.com/chinesehuazhou/guido_blog_translation

許多語法都有支持給規則添加動作的約定,通常是 { 花括號 } 內的一段代碼塊。更確切地說,行動與備選項相關聯。動作塊中的代碼通常與編寫編譯器的語言相同,如 C 語言,增加一些工具,用于引用備選項中的條目。在 Python 原始的 pgen 中,我沒有添加此功能,但對于這個新項目,我希望使用它。

對于在這一系列博客文章中開發的簡化版解析器生成器,下面是我們采用的做法。

一般而言,動作的語法如下:

                
                  rule:?item?item?item?{?action?1?}?|?item?item?{?action?2?}

                
              

因為它會使語法變得冗長,所以解析器生成器通常支持跨行分割規則,例如:

                
                  rule:?item?item?item?{?action?1?}
????|?item?item?{?action?2}

                
              

它會使語法分析器變得復雜,但可讀性更重要,所以我會使用這種方式。

一個永恒的問題是何時執行動作塊。在 Yacc / Bison 中,因為沒有回溯,一旦規則被解析器識別到,就會執行動作塊。每個動作會立即執行,這意味著即使操作具有全局副作用,還是會順利執行(例如更新符號表或其它編譯器數據結構)。

在 PEG 解析器中,因為有無限回溯,我們有其它的選擇:
  • 延遲所有動作,直到解析完所有內容。這對我的目的沒有用,因為我想在解析期間構造一個 AST。
  • 只要識別出動作所對應的備選項就執行之,但要求操作代碼是冪等的(即無論執行多少次,都具有相同的效果)。這意味著可以執行某個動作,但其結果最終會被丟棄。
  • 緩存動作的結果,因此只有第一次在給定位置識別到備選項時,對應的動作才執行。

我要采用第三個選項——正好我們用 packrat 算法緩存東西,所以我們也可以緩存動作的結果。

關于 {花括號} 里面的內容,傳統上是使用 C 語言,它約定用 $ 符號來引用已識別的備選項(例如, $1 引用第一個條目),并賦值給 $$ 以指示動作的結果。

在我看來這太老古董了(我記得曾在 Algol-60 中使用對函數名的賦值,來指定返回值),所以我會用一些更 Pythonic 的方式:在括號內,你需要放置一個單一的表達式,它的值是動作的值,而條目的引用則是一些簡單的名稱,給出著條目的文本。

舉個例子,這是一個簡單計算器,可作加減法:

                
                  start:?expr?NEWLINE?{?expr?}
expr:?expr?'+'?term?{?expr?+?term?}
????|?expr?'-'?term?{?expr?-?term?}
????|?term?{?term?}
term:?NUMBER?{?float(number.string)?}

                
              

當我們運行時,給定輸入 100+50-38-70 ,它會識別出各部分并計算答案,計算成 ((100+50)-38)-70 ,當然得出結果為 42。

一個小細節:在 term 的動作中,變量 number 保存了一個 TokenInfo 對象,因此該動作必須使用其 .string 屬性來獲取字符串形式的標識符。

當一個備選項中多次出現相同的規則名稱時,我們該怎么辦?對同一備選項中出現的規則,解析器生成器會給出唯一的名稱,即在隨后出現的規則上添加 1、2 等等。例如:

                
                  factor:?atom?'**'?atom?{?atom?**?atom1?}
??????|?atom?{?atom?}

                
              

它的實現很無聊,所以我請你們 check out 代碼 ,自己看看。試試這個:

                
                  python3.8?-m?story5.driver?story5/calc.txt?-g?story5.calc.CalcParser

                
              

可視化功能現在支持使用左右箭頭鍵來回移動!

本文內容與示例代碼的授權協議:CC BY-NC-SA 4.0
640?
譯者簡介: 豌豆花下貓,生于廣東畢業于武大,現為蘇漂程序員,有一些極客思維,也有一些人文情懷,有一些溫度,還有一些態度。

優質文章,推薦閱讀:

Python 的整數與 Numpy 的數據溢出

編程語言之問:何時該借用,何時該創造?

GIL 已經被殺死了么?

Python進階:設計模式之迭代器模式

Python 之父的解析器系列之六:給 PEG 語法添加動作_第2張圖片

告訴朋友們,我在看 640?wx_fmt=png

更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 一区二区三区国产免费 | 天天骑天天干 | 91精品国产欧美一区二区 | 日本高清免费在线视频 | 美国免费一级片 | 国产高清在线观看 | 美女爽到呻吟久久久久 | 国产午夜免费视频片夜色 | 久久精品视频免费 | 免费看在线偷拍视频 | 秋霞理论在线视频 | 成人嫩草影院免费观看 | 国产成+人+亚洲+欧美+日韩 | 在线色网| 成人网在线免费观看 | 日本黄色小视频 | 久草中文在线观看 | 在线播放av片 | 成人黄色在线观看 | 国产福利不卡一区二区三区 | 嫩草嫩草嫩草 | 成人在线视频精品 | 欧美福利视频一区二区三区 | 国产黄色网址在线观看 | 九七婷婷狠狠成人免费视频 | 久久久国产一区二区三区 | 黄视频在线观看网站 | 午夜资源在线 | 午夜啪视频 | 久操免费视频 | 在线播放一区二区三区 | 日本无码V视频一区二区 | 欧美一极视频 | 天天躁日日躁狠狠很躁 | 桃花综合 | 久久久久国产精品 | 国产69精品久久久久99尤物 | 亚洲欧美综合乱码精品成人网 | 亚洲视频黄色 | 亚洲高清国产拍精品影院 | 日本欧美国产精品第一页久久 |