언어 문법

언어 문법 (Language Grammar)

Solidity의 공식 문법(EBNF 스타일)을 담은 페이지예요. Solidity Parser 문법과 Lexer 문법으로 나뉘며, 이 문법 정의는 언어의 모든 토큰, 타입, 선언, 문을 정확히 규정해요. 컴파일러 구현을 분석하거나 문법의 틀을 이해할 때 참고하는 공식 명세예요. 각 규칙 이름과 터미널·논터미널 기호는 원문 그대로 보존하며, 항목별 설명을 한국어로 덧붙였어요.

출처: 문서

본문

Solidity는 이더리움 플랫폼에서 스마트 컨트랙트를 구현하기 위한 정적으로 타입이 지정된, 컨트랙트 지향의 고수준 언어예요.

다음은 공식 Solidity 문법 정의(SolidityParser / SolidityLexer)를 원문 그대로 보존한 것이에요. 문법 규칙은 원문 표기법 그대로이며, 설명은 한국어 번역이에요.

# Language Grammar 
**grammar SolidityParser **
Solidity is a statically typed, contract-oriented, high-level language for implementing smart contracts on the Ethereum platform. source-unit  On top level, Solidity allows pragmas, import directives, and
definitions of contracts, interfaces, libraries, structs, enums and constants. 'pragma' pragma-token ';' import-directive using-directive contract-definition interface-definition library-definition function-definition constant-variable-declaration struct-definition enum-definition user-defined-value-type-definition error-definition event-definition eof import-directive  Import directives import identifiers from different files. 'import' path 'as' identifier symbol-aliases 'from' path '*' 'as' identifier 'from' path ';' path  Path of a file to be imported. non-empty-string-literal symbol-aliases  List of aliases for symbols to be imported. '{' identifier 'as' identifier ',' '}' contract-definition  Top-level definition of a contract. 'abstract' 'contract' identifier 'layout' 'at' expression 'is' inheritance-specifier ',' '{' contract-body-element '}' interface-definition  Top-level definition of an interface. 'interface' identifier 'is' inheritance-specifier ',' '{' contract-body-element '}' library-definition  Top-level definition of a library. 'library' identifier '{' contract-body-element '}' inheritance-specifier  Inheritance specifier for contracts and interfaces.
Can optionally supply base constructor arguments. identifier-path call-argument-list contract-body-element  Declarations that can be used in contracts, interfaces and libraries. Note that interfaces and libraries may not contain constructors, interfaces may not contain state variables
and libraries may not contain fallback, receive functions nor non-constant state variables. constructor-definition function-definition modifier-definition fallback-function-definition receive-function-definition struct-definition enum-definition user-defined-value-type-definition state-variable-declaration event-definition error-definition using-directive call-argument-list  Arguments when calling a function or a similar callable object.
The arguments are either given as comma separated list or as map of named arguments. '(' expression ',' '{' identifier ':' expression ',' '}' ')' identifier-path  Qualified name. identifier '.' modifier-invocation  Call to a modifier. If the modifier takes no arguments, the argument list can be skipped entirely
(including opening and closing parentheses). identifier-path call-argument-list visibility  Visibility for functions and function types. 'internal' 'external' 'private' 'public' parameter-list  A list of parameters, such as function arguments or return values. type-name data-location identifier ',' constructor-definition  Definition of a constructor.
Must always supply an implementation.
Note that specifying internal or public visibility is deprecated. 'constructor' '(' parameter-list ')' modifier-invocation 'payable' 'internal' 'public' block state-mutability  State mutability for function types.
The default mutability ‘non-payable’ is assumed if no mutability is specified. 'pure' 'view' 'payable' override-specifier  An override specifier used for functions, modifiers or state variables.
In cases where there are ambiguous declarations in several base contracts being overridden,
a complete list of base contracts has to be given. 'override' '(' identifier-path ',' ')' function-definition  The definition of contract, library, interface or free functions.
Depending on the context in which the function is defined, further restrictions may apply,
e.g. functions in interfaces have to be unimplemented, i.e. may not contain a body block. 'function' identifier 'fallback' 'receive' '(' parameter-list ')' visibility state-mutability modifier-invocation 'virtual' override-specifier 'returns' '(' parameter-list ')' ';' block modifier-definition  The definition of a modifier.
Note that within the body block of a modifier, the underscore cannot be used as identifier,
but is used as placeholder statement for the body of a function to which the modifier is applied. 'modifier' identifier '(' parameter-list ')' 'virtual' override-specifier ';' block fallback-function-definition  Definition of the special fallback function. 'fallback' '(' parameter-list ')' 'external' state-mutability modifier-invocation 'virtual' override-specifier 'returns' '(' parameter-list ')' ';' block receive-function-definition  Definition of the special receive function. 'receive' '(' ')' 'external' 'payable' modifier-invocation 'virtual' override-specifier ';' block struct-definition  Definition of a struct. Can occur at top-level within a source unit or within a contract, library or interface. 'struct' identifier '{' struct-member '}' struct-member  The declaration of a named struct member. type-name identifier ';' enum-definition  Definition of an enum. Can occur at top-level within a source unit or within a contract, library or interface. 'enum' identifier '{' identifier ',' '}' user-defined-value-type-definition  Definition of a user defined value type. Can occur at top-level within a source unit or within a contract, library or interface. 'type' identifier 'is' elementary-type-name ';' state-variable-declaration  The declaration of a state variable. type-name 'public' 'private' 'internal' 'constant' override-specifier 'immutable' 'transient' identifier '=' expression ';' constant-variable-declaration  The declaration of a constant variable. type-name 'constant' identifier '=' expression ';' event-parameter  Parameter of an event. type-name 'indexed' identifier event-definition  Definition of an event. Can occur in contracts, libraries or interfaces. 'event' identifier '(' event-parameter ',' ')' 'anonymous' ';' error-parameter  Parameter of an error. type-name identifier error-definition  Definition of an error. 'error' identifier '(' error-parameter ',' ')' ';' user-definable-operator  Operators that users are allowed to implement for some types with using for . '&' '~' '|' '^' '+' '/' '%' '*' '-' '==' '>' '>=' '<' '<=' '!=' using-directive  Using directive to attach library functions and free functions to types.
Can occur within contracts and libraries and at the file level. 'using' identifier-path '{' using-aliases ',' '}' 'for' '*' type-name 'global' ';' using-aliases  identifier-path 'as' user-definable-operator type-name  A type name can be an elementary type, a function type, a mapping type, a user-defined type
(e.g. a contract or struct) or an array type. elementary-type-name function-type-name mapping-type identifier-path '[' expression ']' elementary-type-name  'address' 'payable' 'bool' 'string' 'bytes' signed-integer-type unsigned-integer-type fixed-bytes fixed ufixed function-type-name  'function' '(' parameter-list ')' visibility state-mutability 'returns' '(' parameter-list ')' variable-declaration  The declaration of a single variable. type-name data-location identifier data-location  'memory' 'storage' 'calldata' expression  Complex expression.
Can be an index access, an index range access, a member access, a function call (with optional function call options),
a type conversion, an unary or binary expression, a comparison or assignment, a ternary expression,
a new-expression (i.e. a contract creation or the allocation of a dynamic memory array),
a tuple, an inline array or a primary expression (i.e. an identifier, literal or type name). 'payable' call-argument-list 'type' '(' type-name ')' '++' '--' '!' '~' 'delete' '-' expression 'new' type-name tuple-expression inline-array-expression identifier literal literal-with-sub-denomination elementary-type-name '[' expression ':' expression ']' '.' identifier 'address' '{' identifier ':' expression ',' '}' call-argument-list '++' '--' '**' '*' '/' '%' '+' '-' '<<' '>>' '>>>' '&' '^' '|' '<' '>' '<=' '>=' '==' '!=' '&&' '||' '?' expression ':' '=' '|=' '^=' '&=' '<<=' '>>=' '>>>=' '+=' '-=' '*=' '/=' '%=' expression tuple-expression  '(' expression ',' ')' inline-array-expression  An inline array expression denotes a statically sized array of the common type of the contained expressions. '[' expression ',' ']' identifier  Besides regular non-keyword Identifiers, some keywords like ‘from’ and ‘error’ can also be used as identifiers. identifier 'from' 'error' 'revert' 'global' 'transient' 'layout' 'at' literal  string-literal number-literal boolean-literal hex-string-literal unicode-string-literal literal-with-sub-denomination  number-literal sub-denomination boolean-literal  'true' 'false' string-literal  A full string literal consists of either one or several consecutive quoted strings. non-empty-string-literal empty-string-literal hex-string-literal  A full hex string literal that consists of either one or several consecutive hex strings. hex-string unicode-string-literal  A full unicode string literal that consists of either one or several consecutive unicode strings. unicode-string-literal number-literal  Number literals can be decimal or hexadecimal numbers with an optional unit. decimal-number hex-number block  A curly-braced block of statements. Opens its own scope. '{' statement unchecked-block '}' unchecked-block  'unchecked' block statement  block variable-declaration-statement expression-statement if-statement for-statement while-statement do-while-statement continue-statement break-statement try-statement return-statement emit-statement revert-statement assembly-statement if-statement  If statement with optional else part. 'if' '(' expression ')' statement 'else' statement for-statement  For statement with optional init, condition and post-loop part. 'for' '(' variable-declaration-statement expression-statement ';' expression-statement ';' expression ')' statement while-statement  'while' '(' expression ')' statement do-while-statement  'do' statement 'while' '(' expression ')' ';' continue-statement  A continue statement. Only allowed inside for, while or do-while loops. 'continue' ';' break-statement  A break statement. Only allowed inside for, while or do-while loops. 'break' ';' try-statement  A try statement. The contained expression needs to be an external function call or a contract creation. 'try' expression 'returns' '(' parameter-list ')' block catch-clause catch-clause  The catch clause of a try statement. 'catch' identifier '(' parameter-list ')' block return-statement  'return' expression ';' emit-statement  An emit statement. The contained expression needs to refer to an event. 'emit' expression call-argument-list ';' revert-statement  A revert statement. The contained expression needs to refer to an error. 'revert' expression call-argument-list ';' assembly-statement  An inline assembly block.
The contents of an inline assembly block use a separate scanner/lexer, i.e. the set of keywords and
allowed identifiers is different inside an inline assembly block. 'assembly' '"evmasm"' assembly-flags '{' yul-statement '}' assembly-flags  Assembly flags.
Comma-separated list of double-quoted strings as flags. '(' assembly-flag-string ',' ')' variable-declaration-tuple  A tuple of variable names to be used in variable declarations.
May contain empty fields. '(' ',' variable-declaration ',' variable-declaration ')' variable-declaration-statement  A variable declaration statement.
A single variable may be declared without initial value, whereas a tuple of variables can only be
declared with initial value. variable-declaration '=' expression variable-declaration-tuple '=' expression ';' expression-statement  expression ';' mapping-type  'mapping' '(' mapping-key-type identifier '=>' type-name identifier ')' mapping-key-type  Only elementary types or user defined types are viable as mapping keys. elementary-type-name identifier-path yul-statement  A Yul statement within an inline assembly block.
continue and break statements are only valid within for loops.
leave statements are only valid within function bodies. yul-block yul-variable-declaration yul-assignment yul-function-call yul-if-statement yul-for-statement yul-switch-statement 'leave' 'break' 'continue' yul-function-definition yul-block  '{' yul-statement '}' yul-variable-declaration  The declaration of one or more Yul variables with optional initial value.
If multiple variables are declared, only a function call is a valid initial value. 'let' yul-identifier ':=' yul-expression ',' yul-identifier ':=' yul-function-call yul-assignment  Any expression can be assigned to a single Yul variable, whereas
multi-assignments require a function call on the right-hand side. yul-path ':=' yul-expression ',' yul-path ':=' yul-function-call yul-if-statement  'if' yul-expression yul-block yul-for-statement  'for' yul-block yul-expression yul-block yul-block yul-switch-statement  A Yul switch statement can consist of only a default-case (deprecated) or
one or more non-default cases optionally followed by a default-case. 'switch' yul-expression 'case' yul-literal yul-block 'default' yul-block 'default' yul-block yul-function-definition  'function' yul-identifier '(' yul-identifier ',' ')' '->' yul-identifier ',' yul-block yul-path  While only identifiers without dots can be declared within inline assembly,
paths containing dots can refer to declarations outside the inline assembly block. yul-identifier '.' yul-identifier yul-evm-builtin yul-function-call  A call to a function with return values can only occur as right-hand side of an assignment or
a variable declaration. yul-identifier yul-evm-builtin '(' yul-expression ',' ')' yul-boolean  'true' 'false' yul-literal  yul-decimal-number yul-string-literal yul-hex-number yul-boolean hex-string yul-expression  yul-path yul-function-call yul-literal
**grammar SolidityLexer **
fixed-bytes  Bytes types of fixed length. 'bytes1' 'bytes2' 'bytes3' 'bytes4' 'bytes5' 'bytes6' 'bytes7' 'bytes8' 'bytes9' 'bytes10' 'bytes11' 'bytes12' 'bytes13' 'bytes14' 'bytes15' 'bytes16' 'bytes17' 'bytes18' 'bytes19' 'bytes20' 'bytes21' 'bytes22' 'bytes23' 'bytes24' 'bytes25' 'bytes26' 'bytes27' 'bytes28' 'bytes29' 'bytes30' 'bytes31' 'bytes32' sub-denomination  Unit denomination for numbers. 'wei' 'gwei' 'ether' 'seconds' 'minutes' 'hours' 'days' 'weeks' 'years' signed-integer-type  Sized signed integer types.
int is an alias of int256. 'int' 'int8' 'int16' 'int24' 'int32' 'int40' 'int48' 'int56' 'int64' 'int72' 'int80' 'int88' 'int96' 'int104' 'int112' 'int120' 'int128' 'int136' 'int144' 'int152' 'int160' 'int168' 'int176' 'int184' 'int192' 'int200' 'int208' 'int216' 'int224' 'int232' 'int240' 'int248' 'int256' unsigned-integer-type  Sized unsigned integer types.
uint is an alias of uint256. 'uint' 'uint8' 'uint16' 'uint24' 'uint32' 'uint40' 'uint48' 'uint56' 'uint64' 'uint72' 'uint80' 'uint88' 'uint96' 'uint104' 'uint112' 'uint120' 'uint128' 'uint136' 'uint144' 'uint152' 'uint160' 'uint168' 'uint176' 'uint184' 'uint192' 'uint200' 'uint208' 'uint216' 'uint224' 'uint232' 'uint240' 'uint248' 'uint256' non-empty-string-literal  A non-empty quoted string literal restricted to printable characters. '"' double-quoted-printable escape-sequence '"' ''' single-quoted-printable escape-sequence ''' empty-string-literal  An empty string literal '"' '"' ''' ''' single-quoted-printable  Any printable character except single quote or back slash. [\u0020-\u0026\u0028-\u005B\u005D-\u007E] double-quoted-printable  Any printable character except double quote or back slash. [\u0020-\u0021\u0023-\u005B\u005D-\u007E] escape-sequence  Escape sequence.
Apart from common single character escape sequences, line breaks can be escaped
as well as four hex digit unicode escapes \uXXXX and two digit hex escape sequences \xXX are allowed. '\' ['"\\nrt\n\r] 'u' [0-9A-Fa-f] [0-9A-Fa-f] [0-9A-Fa-f] [0-9A-Fa-f] 'x' [0-9A-Fa-f] [0-9A-Fa-f] unicode-string-literal  A single quoted string literal allowing arbitrary unicode characters. 'unicode' '"' ~["\r\n\\] escape-sequence '"' ''' ~['\r\n\\] escape-sequence ''' hex-string  Hex strings need to consist of an even number of hex digits that may be grouped using underscores. 'hex' '"' [0-9A-Fa-f] [0-9A-Fa-f] '_' '"' ''' [0-9A-Fa-f] [0-9A-Fa-f] '_' ''' hex-number  Hex numbers consist of a prefix and an arbitrary number of hex digits that may be delimited by underscores. '0' 'x' [0-9A-Fa-f] '_' decimal-number  A decimal number literal consists of decimal digits that may be delimited by underscores and
an optional positive or negative exponent.
If the digits contain a decimal point, the literal has fixed point type. [0-9] '_' [0-9] '_' '.' [0-9] '_' [eE] '-' [0-9] '_' identifier  An identifier in solidity has to start with a letter, a dollar-sign or an underscore and
may additionally contain numbers after the first symbol. [a-zA-Z$_] [a-zA-Z0-9$_] yul-evm-builtin  Builtin functions in the EVM Yul dialect. 'stop' 'add' 'sub' 'mul' 'div' 'sdiv' 'mod' 'smod' 'exp' 'not' 'lt' 'gt' 'slt' 'sgt' 'eq' 'iszero' 'and' 'or' 'xor' 'byte' 'shl' 'shr' 'sar' 'clz' 'addmod' 'mulmod' 'signextend' 'keccak256' 'pop' 'mload' 'mstore' 'mstore8' 'sload' 'sstore' 'tload' 'tstore' 'msize' 'gas' 'address' 'balance' 'selfbalance' 'caller' 'callvalue' 'calldataload' 'calldatasize' 'calldatacopy' 'extcodesize' 'extcodecopy' 'returndatasize' 'returndatacopy' 'mcopy' 'extcodehash' 'create' 'create2' 'call' 'callcode' 'delegatecall' 'staticcall' 'return' 'revert' 'selfdestruct' 'invalid' 'log0' 'log1' 'log2' 'log3' 'log4' 'chainid' 'origin' 'gasprice' 'blockhash' 'blobhash' 'coinbase' 'timestamp' 'number' 'difficulty' 'prevrandao' 'gaslimit' 'basefee' 'blobbasefee' 'slotnum' yul-identifier  Yul identifiers consist of letters, dollar signs, underscores and numbers, but may not start with a number.
In inline assembly there cannot be dots in user-defined identifiers. Instead see yulPath for expressions
consisting of identifiers with dots. [a-zA-Z$_] [a-zA-Z0-9$_] yul-hex-number  Hex literals in Yul consist of a prefix and one or more hexadecimal digits. '0' 'x' [0-9a-fA-F] yul-decimal-number  Decimal literals in Yul may be zero or any sequence of decimal digits without leading zeroes. '0' [1-9] [0-9] yul-string-literal  String literals in Yul consist of one or more double-quoted or single-quoted strings
that may contain escape sequences and printable characters except unescaped line breaks or
unescaped double-quotes or single-quotes, respectively. '"' double-quoted-printable escape-sequence '"' ''' single-quoted-printable escape-sequence ''' pragma-token  Pragma token. Can contain any kind of symbol except a semicolon.
Note that currently the solidity parser only allows a subset of this.

문법에서 주요 생산 규칙의 의미를 정리하면 다음과 같아요:

  • source-unit(소스 유닛): 최상위에서 Solidity는 pragma, import 지시문, 그리고 컨트랙트·인터페이스·라이브러리·구조체·enum·상수의 정의를 허용해요.
  • import-directive(임포트 지시문): 다른 파일에서 식별자를 임포트해요.
  • contract-definition / interface-definition / library-definition: 컨트랙트·인터페이스·라이브러리의 최상위 정의예요. 인터페이스와 라이브러리는 생성자를 포함할 수 없고, 인터페이스는 상태 변수를, 라이브러리는 fallback·receive 함수와 비-상수 상태 변수를 포함할 수 없어요.
  • function-definition / modifier-definition / constructor-definition / fallback / receive: 함수, 수정자, 생성자, 특별한 fallback·receive 함수의 정의예요.
  • struct / enum / user-defined-value-type / state-variable / constant-variable / event / error: 구조체, enum, 사용자 정의 값 타입, 상태 변수, 상수, 이벤트, 에러의 정의예요.
  • expression / statement / yul-statement: 표현식과 문, 그리고 인라인 어셈블리 블록 안의 Yul 문이에요. 인라인 어셈블리 블록은 별도 스캐너/렉서를 사용해, 키워드 집합과 허용된 식별자가 인라인 어셈블리 블록 안에서 다르다는 점에 주의하세요.
  • SolidityLexer: 고정 바이트 타입(bytes1…bytes32), 단위 접미사(wei, gwei, ether, seconds…years), 부호 있는/없는 정수 타입(int8…int256, uint8…uint256), 문자열·hex·유니코드 리터럴, 식별자, Yul 내장 함수(stop, add, mload, sstore, call 등)의 토큰 규칙을 정의해요.

더 알아보기 (Learn more)