루아의 전체 문법
루아의 전체 문법 (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)" 절에서 세부 규칙을 다뤄요.
본문
문법 해석 참고
- 문법의
{ ... }반복과[ ... ]선택을 활용하면 우선순위에 따라 중첩된 표현식을 기술할 수 있어요. prefixexp(접두사 표현식)는 변수·함수 호출·괄호로 시작하고, 체이닝(a.b.c,f():g())이 가능해요.- 문장(
stat)은 블록(block)을 구성하고, 블록은 함수 본문이나 제어 구조의 본문이 돼요.
청크 루트
최상위 "chunk"는 단순히 block이에요. 따라서 스크립트 파일 자체가 하나의 블록이고, 그 안에 문장들이 순차 실행돼요.