루아의 전체 문법

루아의 전체 문법 (The Complete Syntax of Lua)

이 절에서는 루아 5.4의 전체 문법(grammar)을 제시해요. 여기에 적힌 표기법은 확장된 BNF(Backus-Naur form)예요.

  • 꺾쇠 괄호 <name> — 비-터미널(non-terminal) 기호.
  • 큰따옴표 "text" — 터미널 기호(리터럴 텍스트).
  • 구분은 공백.
  • 선택 요소[ ... ]로 표시.
  • 반복{ ... }로 표시.
  • 대안은 세로 막대(|) 또는 줄바꿈으로 표시.
  • exp 는 표현식을, name 은 식별자를 나타내요.
  • 문법 규칙의 끝은 마침표(.)로 표시돼요.

전체 문법 규칙

chunk ::= block

block ::= {stat} [retstat]

stat ::=  ';'
       | varlist '=' explist
       | functioncall
       | label
       | break
       | goto Name
       | do block end
       | while exp do block end
       | repeat block until exp
       | if exp then block {elseif exp then block} [else block] end
       | for Name '=' exp ',' exp [',' exp] do block end
       | for namelist in explist do block end
       | function funcname funcbody
       | local function Name funcbody
       | local attnamelist ['=' explist]
       | return [explist] [';']

retstat ::= return [explist] [';']

label ::= '::' Name '::'

funcname ::= Name {'.' Name} [':' Name]

varlist ::= var {',' var}

var ::=  Name
      | prefixexp '[' exp ']'
      | prefixexp '.' Name

namelist ::= Name {',' Name}

attnamelist ::=  Name attrib {',' Name attrib}

attrib ::= '<' Name '>'

explist ::= exp {',' exp}

exp ::=  nil | false | true | Numeral | LiteralString | '...' | functiondef
       | prefixexp | tableconstructor | exp binop exp | unop exp

prefixexp ::= var | functioncall | '(' exp ')'

functioncall ::=  prefixexp args | prefixexp ':' Name args

args ::=  '(' [explist] ')' | tableconstructor | LiteralString

functiondef ::= function funcbody

funcbody ::= '(' [parlist] ')' block end

parlist ::= namelist [',' '...'] | '...'

tableconstructor ::= '{' [fieldlist] '}'

fieldlist ::= field {fieldsep field} [fieldsep]

field ::= '[' exp ']' '=' exp | Name '=' exp | exp

fieldsep ::= ',' | ';'

binop ::=  '+' | '-' | '*' | '/' | '//' | '%' | '^'
        | '..' | '<' | '<=' | '>' | '>=' | '==' | '~='
        | '&' | '|' | '~' | '<<' | '>>'
        | 'and' | 'or'

unop ::= '-' | 'not' | '#' | '~'

터미널 기호와 정의

  • Name — 식별자: 문자·숫자·밑줄의 연속, 숫자로 시작 불가 (예약어 제외).
  • Numeral — 숫자 리터럴.
  • LiteralString — 문자열 리터럴.
  • 예약어(reserved words): and break do else elseif end false for function goto if in local nil not or repeat return then true until while.

문법의 미묘한 점

  • return 은 블록의 마지막 문장이어야 해요 (그 뒤에 다른 문장이 오면 안 됨). 블록 밖(최상위)에서는 청크의 마지막에도 올 수 있어요.
  • break 는 루프 안에서만 사용 가능하고, 문장으로서 허용돼요.
  • goto 는 레이블(::name::)로 점프하며, 스코프 규칙을 지켜야 해요.
  • ...(vararg)는 가변 인자 함수 안에서만 사용 가능해요.
  • 함수 호출은 문장으로 쓸 수 있고(functioncall), 반환값은 무시돼요.
  • local 선언은 attrib(<close> 등)를 가질 수 있어요.
  • 우선순위binop/unop의 조합 문법과 표준 우선순위 표에 따라 결정돼요 (3.4.8 절 참조).

문법 요약 예시

몇 가지 기본 문장 문법을 실제 코드와 대응해 보면:

-- 청크와 블록
local x = 1
if x > 0 then
  print("양수")
else
  print("음수")
end

-- for와 repeat
for i = 1, 3 do print(i) end
repeat x = x - 1 until x == 0

-- 함수 정의와 가변 인자
local function sum(...)
  local s = 0
  for _, v in ipairs({...}) do s = s + v end
  return s
end

-- 테이블 생성자와 메타테이블
local t = setmetatable({1, 2, 3}, {__index = { extra = "속성" }})

매크로/마이크로 표기법 참고

이 문법은 루아 컴파일러가 실제로 수용하는 언어를 정의해요. Numeral, LiteralString, Name 등은 위 "어휘 규약 (Lexical Conventions)" 절에서 세부 규칙을 다뤄요.

출처: 루아의 전체 문법 (The Complete Syntax of Lua)

본문

문법 해석 참고

  • 문법의 { ... } 반복과 [ ... ] 선택을 활용하면 우선순위에 따라 중첩된 표현식을 기술할 수 있어요.
  • prefixexp(접두사 표현식)는 변수·함수 호출·괄호로 시작하고, 체이닝(a.b.c, f():g())이 가능해요.
  • 문장(stat)은 블록(block)을 구성하고, 블록은 함수 본문이나 제어 구조의 본문이 돼요.

청크 루트

최상위 "chunk"는 단순히 block이에요. 따라서 스크립트 파일 자체가 하나의 블록이고, 그 안에 문장들이 순차 실행돼요.

더 알아보기