>

Lua 지식 (그리고 Lua 매뉴얼에서 읽은 내용에 따르면)에서 나는 Lua의 식별자가 AZ&az&_&numeric으로 만 제한되어 있다는 느낌을 받았습니다. 숫자 또는 예약 키워드 (예 : local local = 123 ) ).

이제 식별자에 모든 종류의 이상한 문자를 사용하는 (난독 화 된) Lua 프로그램을 실행했습니다.

https://i.imgur.com/HPLKMxp.png

-- Most likely, copy+paste won't work. Download the file from https://tknk.io/7HHZ
print(_VERSION .. " " .. (jit and "JIT" or "non-JIT"))
local T = {}
T.math = T.math or {}
T.math.​â®â€‹âŞâ®â€‹­ď»żâ€Śâ€­âŽ­ = math.sin
T.math.â¬â€‹â­â¬â­â«â®â€­â€¬ = math.cos
for k, v in pairs(T.math) do print(k, v) end

출력 :

Lua 5.1 JIT
â¬â€‹â­â¬â­â«â®â€­â€¬ function: builtin#45
​â®â€‹âŞâ®â€‹­ď»żâ€Śâ€­âŽ­ function: builtin#44

이 문자 세트가 식별자에 허용되는 이유는 확실하지 않습니다.
다시 말해, 왜 완전히 유효한 루아 프로그램입니까?


  • 답변 # 1

    일부 언어와 달리 Lua는 공식적인 사양으로 정의되지 않으며, 모든 우발 상황을 다루고 Lua의 모든 행동을 완전히 설명합니다. "어떤 문자 세트가 Lua 파일로 인코딩되어 있는지"와 같은 단순한 것은 실제로 Lua의 설명서에 설명되어 있지 않습니다.

    식별자에 대한 모든 문서는 다음과 같습니다.

    와이즈 비즈 그러나 "편지"가 무엇인지 실제로 말하는 것은 없습니다. Lua가 사용하는 문자 집합에 대한 정의조차 없습니다. 따라서 본질적으로 구현에 따라 다릅니다. "편지 (letter)"는 ... 구현체가 원하는 모든 것입니다.

    루아 구현을 작성한다고 가정 해 봅시다. 또한 사용자가 유니 코드로 인코딩 된 문자열 (즉, Lua 텍스트내에있는 문자열)을 제공 할 수 있기를 원합니다. 루아 5.3이 필요합니다. 그러나 파일에 UTF-16 인코딩을 사용하지 않아도됩니다 (

    Names(also calledidentifiers) in Lua can be any string of letters, digits, and underscores, not beginning with a digit and not being a reserved word.

    때문에  짧은 바이트가 아닌 바이트 시퀀스를 가져옵니다). 따라서 Lua 구현은 lua_load 에서 얻는 바이트 시퀀스를 가정합니다.  유니 코드 문자를 사용하는 문자열을 작성할 수 있도록 UTF-8로 인코딩됩니다.

    이 구현의 어휘 분석기/파서 부분을 작성할 때, 이것을 어떻게 처리 하는가? UTF-8을 처리하는 가장 간단하고 쉬운 방법은UTF-8을 처리하지 않는 것입니다. 실제로, 그것은 그 인코딩의 요점입니다. Lua가 특정 기호로 정의한 모든 내용은 ASCII로 인코딩되고 ASCII 텍스트도 같은 의미의 UTF-8 텍스트이므로 기본적으로 UTF-8 문자열을 ASCII 문자열처럼 취급 할 수 있습니다. In-Lua 문자열의 경우 문자열의 시작 문자와 끝 문자 사이의 바이트 시퀀스 만 복사하면됩니다.

    그래서 어휘 분석기는 어떻게합니까? 글쎄, 당신은 위의 질문을 할 수 있습니다. 또는 당신은 훨씬 간단한 질문을 할 수 있습니다 : 문자가 공백, 제어 문자, 숫자 또는 기호입니까? "편지"는 단지그중 하나가 아닌것입니다.

    루아는 "심볼"로 간주되는 것을 정의합니다. ASCII는 제어 문자, 공백 및 숫자를 알려줍니다. 이러한 구현에서 ASCII 이외의 값을 가진 UTF-8 코드 단위는letter입니다. 기술적으로 이러한 코드 단위가 유니 코드가 "기호"로 생각하는 것으로 디코딩하더라도 어휘 분석기는이를 문자로 위협합니다.

    이 간단한 형태의 UTF-8 어휘 분석은 빠른 성능과 낮은 메모리 오버 헤드를 제공합니다. UTF-8을 유니 코드 코드 포인트로 디코딩 할 필요가 없으며 코드 포인트가 "기호"인지 "공백"인지 여부를 알려주는 거대한 유니 코드 테이블이 필요하지 않습니다. 물론 이것은 많은 ASCII 기반 Lua 구현에서 자연스럽게 나올 수도 있습니다.

    따라서 대부분의 Lua 구현은 우연히 만 이러한 방식으로 수행합니다. 더 많은 일을하려면 고의적 인 노력이 필요합니다.

    또한 사용자는 유니 코드 문자 시퀀스를 식별자로 사용할 수 있습니다. 이는 누군가 키워드 (키워드 제외)로 모국어로 코드를 쉽게 작성할 수 있음을 의미합니다.

    그러나또한은 난독 처리자가 의미없는 바이트 문자열 인 "식별자"를 만드는 많은 방법을 가지고 있음을 의미합니다. 실제로, 유니 코드에는 동일한 명백한 유니 코드 문자열을 "맞추기"하는 여러 가지 방법이 있기 때문에 (바이트를 직접 검사하지 않는 한) 난독 화기는 텍스트 편집기에서 렌더링 될 때표시되는 식별자를 모두 리깅 할 수 있습니다. 실제로는 다른 문자열이면서 동일한 텍스트를 사용합니다.

  • 답변 # 2

    명명하기 위해 오직 하나의 식별자 lua_load 만 있습니다

    T   T.math 에 대한 설탕 구문입니다  이것은 또한 난독 화 문자열로 확장됩니다. T["math"] 를 갖는 것은 완벽하게 유효합니다  문자를 포함하거나 숫자로 시작하십시오.

    이제 key 를 사용할 수있게되었습니다.  오히려 .  식별자의 제한을 준수하지 않는 문자열에는 작동하지 않습니다. 이러한 제한에 대한 자세한 내용은 Nicol Bolas의 답변을 참조하십시오.

    [ ]

  • 이전 c# - Dapper QueryMultiple의 첫 번째 선택 결과에 액세스 (다 대다)
  • 다음 optimization - Java에서 for-each 루프의 마지막 반복 감지