[루아1.1] lua.stx 읽기 (4)

3 분 소요

Lua.stx (4)

이제 Lua.stx 파일을 반 정도 읽었습니다. 정말 길군요. 계속 읽어 나가겠습니다.

dimension    : /* empty */	{ code_byte(PUSHNIL); incr_ntemp();}
	     | expr1
	     ;
	     
functioncall : functionvalue  {code_byte(PUSHMARK); $<vInt>$ = ntemp; incr_ntemp();}
                '(' exprlist ')' { code_byte(CALLFUNC); ntemp = $<vInt>2-1;}

functionvalue : var {lua_pushvar ($1); } 
	      ;
		
exprlist  :	/* empty */		{ $$ = 1; }
	  |	exprlist1		{ $$ = $1; }
	  ;
		
exprlist1 :	expr			{ $$ = $1; }
	  |	exprlist1 ',' {if (!$1){lua_codeadjust (ntemp+1); incr_ntemp();}} 
                 expr {$$ = $4;}

문법이 짧아서 묶어서 한 번에 읽겠습니다. dimension은 expr 문법의 우항중 하나 입니다. 그런데 dimension에서 다시 expr1 문법으로 갔다가 expr1은 expr로 가므로 expr 문법에 있는 다를 사칙연산 문법처럼 그냥 expr1을 써도 됩니다. 그런데 굳이 dimension이라고 만든 이유는 다른 문법 몇 개처럼 C 언어 코드를 따로 넣고 싶어서 만든 문법으로 보입니다. 아님 말고요. :) functioncall는 이름이 의미를 그대로 설명하고 있습니다. exprlist는 exprlist1와 같이 봐야합니다. 그런데 exprlist1 마지막 우항에 C 언어 코드가 이상하네요. $$=$4인데, 코드상으로는 $4가 나오면 에러거든요.. 이게 왜 되는건지 모르겠습니다. 모르는것 투성이군요.

parlist  :	/* empty */
	  |	parlist1
	  ;
		
parlist1 :	NAME		  
		{
		 localvar[nlocalvar]=lua_findsymbol($1); 
		 add_nlocalvar(1);
		}
	  |	parlist1 ',' NAME 
		{
		 localvar[nlocalvar]=lua_findsymbol($3); 
		 add_nlocalvar(1);
		}
	  ;
		
objectname :	/* empty */ 	{$$=-1;}
	   |	NAME		{$$=lua_findsymbol($1);}
	   ;

parlist는 비어 있거나 콤마로 구분한 변수 이름 나열입니다. objectname은 비어 있거나 변수 이름 한 개 인데, 루아 테이블 자료 구조를 선언할 때 생성자 이름을 지정하거나 생략할 때 쓰는 문법 규칙입니다.

fieldlist  : '{' ffieldlist '}'  
	      { 
	       flush_record($2%FIELDS_PER_FLUSH); 
	       $$ = $2;
	      }
           | '[' lfieldlist ']'  
	      { 
	       flush_list($2/FIELDS_PER_FLUSH, $2%FIELDS_PER_FLUSH);
	       $$ = $2;
     	      }
	   ;

ffieldlist : /* empty */   { $$ = 0; }
           | ffieldlist1   { $$ = $1; }
           ;

ffieldlist1 : ffield			{$$=1;}
	   | ffieldlist1 ',' ffield	
		{
		  $$=$1+1;
		  if ($$%FIELDS_PER_FLUSH == 0) flush_record(FIELDS_PER_FLUSH);
		}
	   ; 

ffield      : NAME {$<vWord>$ = lua_findconstant($1);} '=' expr1 
	      { 
	       push_field($<vWord>2);
	      }
           ;

lfieldlist : /* empty */   { $$ = 0; }
           | lfieldlist1   { $$ = $1; }
           ;

lfieldlist1 : expr1  {$$=1;}
	    | lfieldlist1 ',' expr1
		{
		  $$=$1+1;
		  if ($$%FIELDS_PER_FLUSH == 0) 
		    flush_list($$/FIELDS_PER_FLUSH - 1, FIELDS_PER_FLUSH);
		}
            ;

사실 아직 읽지 않은 상태에서 글을 쓰기 위해 코드에서 복사 붙이기 할 때 문법 규칙에 공통적으로 field가 들어가길래 하나로 묶어서 가져왔습니다. 관련이 있으니까 같은 키워드를 공유하겠죠. 전에 루아 문서에서 찾은 것에 따르면 필드는 루아 테이블 자료구조의 아이템을 뜻합니다. 중괄호({})나 대괄호([])로 묶은 블럭안에 여러개를 선언할 수 있습니다. ffieldlist 문법을 보니 비어 있는 테이블도 선언 가능한가보네요. 각 필드는 콤마로 구분합니다. 필드 자체는 “변수명 = 수식” 형태입니다. 혹은 이름 없는 값으로 수식을 연달아 쓸 수도 있으면 이 경우에는 C 언어의 배열처럼 쓰는가 보네요.

varlist1  :	var			
	  {
	   nvarbuffer = 0; 
           varbuffer[nvarbuffer] = $1; incr_nvarbuffer();
	   $$ = ($1 == 0) ? 1 : 0;
	  }
	  |	varlist1 ',' var	
	  { 
           varbuffer[nvarbuffer] = $3; incr_nvarbuffer();
	   $$ = ($3 == 0) ? $1 + 1 : $1;
	  }
	  ;
		
var	  :	NAME
	  {
	   Word s = lua_findsymbol($1);
	   int local = lua_localname (s);
	   if (local == -1)	/* global var */
	    $$ = s + 1;		/* return positive value */
           else
	    $$ = -(local+1);		/* return negative value */
	  }
	  
	  |	var {lua_pushvar ($1);} '[' expr1 ']' 
	  {
	   $$ = 0;		/* indexed variable */
	  }
	  |	var {lua_pushvar ($1);} '.' NAME
	  {
	   code_byte(PUSHSTRING);
	   code_word(lua_findconstant($4)); incr_ntemp();
	   $$ = 0;		/* indexed variable */
	  }
	  ;
		
localdeclist  : NAME {localvar[nlocalvar]=lua_findsymbol($1); $$ = 1;}
     	  | localdeclist ',' NAME 
	    {
	     localvar[nlocalvar+$1]=lua_findsymbol($3); 
	     $$ = $1+1;
	    }
	  ;
		
decinit	  : /* empty */
	  | '=' exprlist1
	  ;
	  
setdebug  : DEBUG {lua_debug = $1;}

varlist1는 변수를 연속해서 기술하는 규칙입니다. 역시 콤마로 구분해서 연속으로 기술합니다. 변수 자체는 var 문법으로 표현합니다. 변수 이름 자체를 쓰거나 C 언어의 배열 표시처럼 대괄호로 인덱스를 지정합니다. 인덱스는 수식으로 계산할 수 있습니다. 인덱스를 점으로 구분할 수도 있습니다. A.idx처럼 쓰는 것이지요. 루아 문서에는 둘은 같은 동작이고 그냥 문법적으로 다른 표현인 것이라고 합니다. 영어로는 syntax sugar라고 합니다. localdeclist는 LOCAL 토큰 뒤에 오는 문법 규칙입니다. NAME 토큰이 콤마로 연속해서 나오는 다른 문법과 표현은 같지만 해석할 때 값을 가져오는 변수가 localvar 배열이기 때문에 문법을 분리한 것으로 보입니다.

댓글남기기