2014-10-03 4 views
0

나는 내 자신의 "스크립팅 언어"를 만들려고 노력하고있다.이 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

답변

1

가장 쉬운 해결책은

(.*) -- 0 or more repetitions 

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

받는

(.-) -- 0 or more lazy repetitions 

에서 마지막 캡처 그룹을 변경하는 것입니다 - 수정 자에 따라 PiL은 가장 짧은 시퀀스와 일치합니다.

그러나, 내 댓글에 언급 한 바와 같이, 나는 패턴 매칭을 사용하여 언어 파서를 작성 조언을하지 않을 것입니다. 그것은 (복잡한 경우를 방지하기 위해) 정말로 복잡한 패턴을 필요로하고 아마도 다른 사람들에게 불분명 할 것입니다.

관련 문제