[譯] 用javascript實現一門編程語言-寫一個解析器

目錄

  1. 用javascript實現一門編程語言-前言
  2. 用javascript實現一門編程語言-語言構想
  3. 用javascript實現一門編程語言-寫一個解析器
  4. 用javascript實現一門編程語言-字符輸入流

寫一個解析器

解析器的實現是須要根據語言特性來實現的,是一個較爲複雜的任務。事實上,咱們須要將一段代碼或者字母轉換爲抽象語法樹 (abstract syntax tree, AST)。抽象語法樹是程序在內存中展示的一種形式,抽象表示它不關心是由什麼源碼構成的,可是他很確信是符合語義學的。javascript

例如:java

sum = lambda(a, b) {
    a + b;
}
print(sum(1, 2));
複製代碼

解析器會將上面的代碼轉換爲一個javascript對象:正則表達式

{
  type: "prog",
  prog: [
    // 第一行
    {
      type: "assign",
      operator: "=",
      left: { type: "var", value: "sum" },
      right: {
        type: "lambda",
        vars: [ "a", "b" ],
        body: {
          // body 部分也應該是 prog 類型,由於它包含一個表達式
          type: "binary",
          operator: "+",
          left: { type: "var", value: "a" },
          right: { type: "var", value: "b" }
        }
      }
    },
    // 第二行
    {
      type: "call",
      func: { type: "var", value: "print" },
      args: [{
        type: "call",
        func: { type: "var", value: "sum" },
        args: [ { type: "num", value: 1 },
                { type: "num", value: 2 } ]
      }]
    }
  ]
}
複製代碼

寫一個解析器最大的困難在於如何合理的組織代碼。解析器應該站在比讀取字符更高的層面。這裏有一些建來控制程序的適度的複雜性:編程

  • 寫小而精的函數。每一個函數只作一件事,並把它作好。
  • 不要用正則表達式去解析。在寫詞法分析器的時候正則表達式頗有用,可是建議儘可能不要把它用在很簡單的事情上
  • 不要嘗試去猜。當不肯定解析什麼的時候,拋出一個包含位置的錯誤,好比: 第2行25列錯誤

爲了保持膽碼的簡潔性,我將代碼分割成了三部分,未來會被分割成更小的函數:bash

  • 字符輸入流
  • token輸入流
  • 解析器

原文連接: lisperator.net/pltut/parse…編程語言

相關文章
相關標籤/搜索