c.f. 구문 트리
compilation_unit() : {}
{
import_stmts() top_defs() <EOF>
}
imports_stmts() : {}
{
(import_stmt())*
}
import_stmt() : {}
{
<IMPORT> name() ("." name())* ";"
}
top_defs() : {}
{
( LOOKAHEAD(storage() typeref() <IDENTIFIER> "(") defun() // 함수 정의
| LOOKAHEAD(3) defvars() // 변수 정의
| defconst() // 정수 정의
| defstruct() // 구조체 정의
| defunion() // 공용체 정의
| typedef() )*
}
defun() : {}
{
storage() typeref() name() "(" params() ")" block()
}
params() : {}
{
LOOKAHEAD(<VOID> ")") <VOID>
| fixedparams() ["," "..."]
}
fixedparams() : {}
{
param() ( LOOKAHEAD(2) "," param() )*
}
param() : {}
{
type() name()
}
defvars() : {}
{
storage() type() name() ["=" expr()] ( "," name() ["=" expr()] )* ";"
}
storage(): {}
{
[<STATIC>]
}
defstruct() : {}
{
<STRUCT> name() member_list() ";"
}
defunion() : {}
{
<UNION> name() member_list() ";"
}
member_list() : {}
{
"{" ( slot() ";" )* "}"
}
slot() : {}
{
type() name()
}
typedef() : {}
{
<TYPEDEF> typeref() <IDENTIFIER> ";"
}
type() : {}
{
typeref()
}
typeref() : {}
{
typeref_base()
( LOOKAHEAD(2) "[" "]" // 길이가 지정되어 있지 않은 배열
| "[" <INTEGER> "]" // 길이가 지정되어 있는 배열
| "*"
| "(" param_typerefs() ")" // 함수 포인터
)*
}
typeref_base() : {}
{
<VOID>
| <CHAR>
| <SHORT>
| <INT>
| <LONG>
| LOOKAHEAD(2) <UNSIGNED> <CHAR>
| LOOKAHEAD(2) <UNSIGNED> <SHORT>
| LOOKAHEAD(2) <UNSIGNED> <INT>
| <UNSIGNED> <LONG>
| <STRUCT> <IDENTIFIER>
| <UNION> <IDENTIFIER>
| LOOKAHEAD({isType(getToken(1).image)}) <IDENTIFIER> // typedef로 정의된 타입
}
stmts() : {}
{
( stmt() )*
}
stmt() : {}
{
( ";"
| LOOKAHEAD(2) labeled_stmt()
| expr() ";"
| block()
| if_stmt()
| while_stmt()
| dowhile_stmt()
| for_stmt()
| switch_stmt()
| break_stmt()
| continue_stmt()
| goto_stmt()
| return_stmt() )
}
if_stmt() : {}
{
<IF> "(" expr() ")" stmt() [LOOKAHEAD(1) <ELSE> stmt()]
}
while_stmt() : {}
{
<WHILE> "(" expr() ")" stmt()
}
for_stmt() : {}
{
<FOR> "(" [expr()] ";" [expr()] ";" [expr()] ")" stmt()
}
break_stmt() : {}
{
<BREAK> ";"
}
return_stmt() : {}
{
LOOKAHEAD(2) <RETURN> ";"
| <RETURN> expr() ";"
}
block() : {}
{
"{" defvar_list() stmts() "}"
}
defvar_list() : {}
{
( defvars() )*
}
expr() : {}
{
LOOKAHEAD(term() "=") term() "=" expr()
| LOOKAHEAD(term() opassign_op()) term() opassign_op() expr()
| expr10()
}
opassign_op(): {}
{
( "+="
| "-="
| "*="
| "/="
| "%="
| "&="
| "|="
| "^="
| "<<="
| ">>=" )
}
expr10() : {}
{
expr9() ["?" expr() ":" expr10()]
}
expr9() : {}
{
expr8() ( "||" expr8() )*
}
expr8() : {}
{
expr7() ( "&&" expr7() )*
}
expr7() : {}
{
expr6() ( ">" expr6()
| "<" expr6()
| ">=" expr6()
| "<=" expr6()
| "==" expr6()
| "!=" expr6() )*
}
expr6() : {}
{
expr5() ( "|" expr5() )*
}
expr5() : {}
{
expr4() ( "^" expr4() )*
}
expr4() : {}
{
expr3() ( "&" expr3() )*
}
expr3() : {}
{
expr2() ( ">>" expr2()
| "<<" expr2() )*
}
expr2() : {}
{
expr1() ( "+" expr1()
| "-" expr1() )*
}
expr1() : {}
{
term() ( "*" term()
| "/" term()
| "%" term() )*
}
term() : {}
{
LOOKAHEAD( "(" type() ) "(" type() ")" term()
| unary()
}
unary() : {}
{
"++" unary()
| "--" unary()
| "+" term()
| "-" term()
| "!" term()
| "~" term()
| "*" term()
| "&" term()
| LOOKAHEAD(3) <SIZEOF> "(" type() ")"
| <SIZEOF> unary()
| postfix()
}
postfix() : {}
{
primary() ( "++"
| "--"
| "[" expr() "]"
| "." name()
| "->" name()
| "(" args() ")" )*
}
args() : {}
{
[ expr() ( "," expr() )* ]
}
name(): {}
{
<IDENTIFIER>
}
primary() : {}
{
<INTEGER>
| <CHARACTER>
| <STRING>
| <IDENTIFIER>
| "(" expr() ")"
}