2014-10-03 62 views
0

我正在搞亂Lua試圖創建自己的「腳本語言」。是否可以修復這個gsub模式?

它實際上只是一個轉換爲Lua代碼的字符串,然後通過使用loadstring來執行。我的字符串模式有問題。當你分支時(例如,在變量聲明中定義一個變量)它就會出錯。例如,下面的代碼將錯誤:

local code = [[ 
    define x as private: function() 
     define y as private: 5; 
    end; 
]] 
--defining y inside of another variable declaration, causes error 

發生這種情況,因爲該模式來聲明一個變量首先查找關鍵字「定義」,直到分號發現捕獲的一切。因此,爲x將被定義:

function() 
    define y as private: 5 --found a semicolon, set x to capture 

我想我的問題是,是否有可能直到達到正確的忽略分號?這是我到目前爲止的代碼:

local lang = { 
    ["define(.-)as(.-):(.-);"] = function(m1, m2, m3) 
     return (
      m2 == "private" and " local " .. m1 .. " = " .. m3 .. " " or 
      m2 == "global" and " " .. m1 .. " = " .. m3 .. " " or 
      "ERROR IN DEFINING " .. m1 
     ) 
    end, 
} 

function translate(code) 
    for pattern, replace in pairs(lang) do 
     code = code:gsub(pattern, replace) 
    end 
    return code 
end 

local code = [[ 

    define y as private: function() 
     define x as private: 10; 
    end; 

]] 

loadstring(translate(code:gsub("%s*", "")))() 
--remove the spaces from code, translate it to Lua code through the 'translate' function, then execute it with loadstring 
+1

通常你需要一個類似遞歸的算法來處理這些嵌套的定義。在你的情況下,一個簡單的模式匹配不會很容易處理。我會建議逐字閱讀代碼,並決定如何處理下一個單詞。這將像您自己的語言的自定義解析器。 – Moop 2014-10-03 19:01:37

回答

1

最簡單的解決方法是從

(.-) -- 0 or more lazy repetitions 

改變你的最後一個捕獲組

(.*) -- 0 or more repetitions 

pattern = 'define(.-)as(.-):(.*);' 

的根據。-修飾符PiL匹配最短的序列。

但是,正如我的評論所指出的,我不會建議使用模式匹配爲您的語言編寫解析器。它要麼需要非常複雜的模式(以防止邊緣情況)並且可能對其他人不清楚。

相關問題