Skip to content

Latest commit

 

History

History
264 lines (175 loc) · 14.7 KB

grammars.md

File metadata and controls

264 lines (175 loc) · 14.7 KB

문법

여기서는 비빔의 문법에 대해 상세히 다룹니다.

공백 문자

비빔에서는 모든 공백 문자를 무시합니다.

심지어는 한 글자 이상의 키워드(~#, #~, ?=)의 사이에도 공백 문자를 사용할 수 있으며, 수를 선언할 때 분자, 분모에 사용되는 수의 각 자릿수 사이에도 공백 문자를 사용할 수 있습니다.

따라서 아래의 표현식은 정상적인 표현식입니다.

1 3  5 ?    = 54  ~
# 주석입니다. #~

따라서 단 하나의 띄어쓰기 없이 한 줄에 비빔 코드를 작성한다 하더라도 문제없이 동작하며, 심지어는 비빔 코드의 모든 문자 사이에 공백 문자를 삽입하여 코드의 길이를 두배로 늘려도 아주 잘 실행됩니다.

인코딩

소스코드 파일

비빔으로 작성된 모든 코드는 UTF-8로 인코딩된 파일로 저장해야만 합니다.

입출력 인코딩

비빔은 입출력을 UTF-8로 인코딩된 유니코드 문자열을 통해서 수행합니다.
비빔에서 @:1 특수 그릇 위치를 사용하는 입출력은 모두 유니코드 값을 담고 있는 그릇으로 처리됩니다. 따라서 비빔에서 '안녕'(U+C548, U+B155) 이라는 문자열은 아래의 그릇과 같습니다.

{
    [0; 50504]
    [1; 45397]
}

주석

비빔에서 주석은 ~# 내용 #~와 같이 주석 시작 키워드 ~#와 주석 끝 키워드 #~ 사이에 원하는 문자열을 작성하여 사용할 수 있습니다. 주석은 여러 줄에 걸쳐 작성하여도 아무 문제가 없습니다.

당연하게도 ~# 주석의 끝은 #~ 입니다. #~와 같은 주석을 작성하면 중간의 #~에서 주석이 끝났으므로, 입니다. #~ 부분의 내용은 주석으로 처리되지 않기 때문에 오류가 발생할 것입니다.

소괄호

소괄호 문자 (, )를 사용하여 표현식의 연산 우선순위를 지정할 수 있습니다. 비빔은 소괄호 안의 표현식을 최우선적으로 평가합니다.

자료형

비빔에서 사용하는 자료형은 수, 면발, 그릇과 널이 있습니다.

비빔에서 '수'란 유리수를 나타내는 자료형입니다. 수는 부동소수점으로 저장되지 않고, 분수꼴로 저장됩니다. 따라서 비빔에서는 유리수 연산에서 부동소수점 오차가 발생하지 않습니다.

비빔에서 수를 표현하기 위해서는 분자와 분모를 표현하는 정수가 사용됩니다. 이 때 사용되는 정수는 음의 정수, 0, 양의 정수를 모두 표현할 수 있어야 합니다.

정수 표현

단순히 어떤 정수를 나타내고 싶다면 양의 십진 정수를 직접 입력하여 사용합니다. 단, 정수 사이에 공백 문자를 제외한 어떠한 문자도 사용해서는 안됩니다.

예를 들어, 표현식 13은 정수 13과 같습니다.

비빔에서 정수는 분모가 1인 수로서 취급합니다. 따라서 분모 연산자 ^를 정수에 사용할 경우 1이 반환됩니다.

분수 구분자 /

정수가 아닌 수를 나타내기 위해서는 분수 구분자 /를 사용합니다. 이 경우 분수 구분자 /의 앞에 사용된 수를 분자로, / 문자 뒤에 사용된 수를 분모로 사용하여 새로운 수를 만듭니다.

예를 들어, 비빔의 표현식 3/5는 유리수 3/5와 동일합니다. 또, 1/3은 유리수 1/3과 동일합니다.

새로운 수를 정의할 때, 비빔은 내부적으로 수를 분모와 분자 모두 정수로 이루어진 기약분수 형태로 변환합니다. 따라서 표현식 (4/5)/(8/5)의 평가 결과는 1/2이 됩니다.

음수

비빔에서는 음수를 바로 정의할 수 있는 방법은 없습니다. 대신 정수 0에서 어떠한 수를 빼서 음수를 표현할 수 있습니다.

예를 들어, 음수 -1/3을 표현하기 위해서는 0 - 1/3과 같이 작성합니다.

면발

면발은 비빔에서 두 개의 표현식으로 이루어진 특별한 자료형입니다. 면발은 면발 시작 키워드[로 시작하여 면발 끝 키워드 ]로 끝나며, 중간에 면발 구분자 ;를 사용하여 두 개의 표현식을 구분합니다. 면발 구분자 ;를 기준으로 앞의 표현식을 면발 번호, 뒤의 표현식을 면발 내용이라고 부릅니다.

예를 들면, 표현식 [3/4; 2/3]은 하나의 면발을 나타내며, 면발 번호는 수 3/4, 면발 내용은 수 2/3입니다.

면발을 정의할 때 면발 번호와 면발 내용 중 어떤 것도 생략할 수 없습니다.

그릇

그릇은 면발들을 담아두는 비빔의 특별한 자료형입니다. 그릇은 그릇 시작 키워드 {와 그릇 끝 키워드 } 사이에 면발들을 특별한 구분자 없이 나열하여 정의합니다.

예를 들면, 아래의 코드는 총 12가닥의 면발을 담고 있는 그릇입니다.

{
    [0; 72]
    [1; 69]
    [2; 76]
    [3; 76]
    [4; 79]
    [5; 32]
    [6; 87]
    [7; 79]
    [8; 82]
    [9; 76]
    [10; 68]
    [11; 10]
}

또한 어떠한 면발도 담고 있지 않는 그릇 역시 정의할 수 있는데, 이 경우에는 간단히 {}와 같이 정의할 수 있습니다.

그릇에 담긴 면발의 면발 번호는 중복될 수 있습니다.

비빔에서 정의되지 않는 연산을 수행한 경우 결과값으로 널을 반환합니다. 널은 아무런 의미가 없는 값이며, 널에 대해 어떤 연산을 수행하더라도 그 결과는 언제나 널이 반환됩니다.

연산자

비빔에서는 다양한 연산자를 지원합니다.

산술 연산자

덧셈 연산자 +

덧셈 연산자 +는 두 수를 더한 결과로 새로운 수를 만듭니다.

예를 들어 1/4 + 1/2의 연산 결과는 3/4가 됩니다.

만약 면발, 그릇 또는 널과 함께 덧셈 연산자를 사용한 경우 평가 결과는 널이 됩니다.

뺄셈 연산자 -

뺄셈 연산자 -는 두 수를 뺀 결과로 새로운 수를 만듭니다.

예를 들어 1/4 - 1/2의 연산 결과는 -1/4가 됩니다.

만약 면발, 그릇 또는 널과 함께 뺄셈 연산자를 사용한 경우 평가 결과는 널이 됩니다.

덧셈 연산자 +

덧셈 연산자 +는 두 수를 더한 새로운 수를 만듭니다.

예를 들어 1/4 + 1/2의 연산 결과는 3/4가 됩니다.

곱셈 연산자 *

곱셈 연산자 *는 두 수를 곱한 결과로 새로운 수를 만듭니다.

예를 들어 1/4 * 1/2의 연산 결과는 1/8가 됩니다.

만약 면발, 그릇 또는 널과 함께 곱셈 연산자를 사용한 경우 평가 결과는 널이 됩니다.

곱셈 연산자를 사용할 때 주의해야 할 점은 곱셈 연산자보다 분수 구분자 /가 더 높은 우선순위를 가진다는 점입니다. 비빔에서 2/3*3/7라는 코드는 분수 구분자부터 평가되어 ((2 / 3) * 3) / 7 -> 2 / 7 이 아닌 (2 / 3) * (3 / 7) -> 2 / 7 과 같은 순서로 평가됩니다.

분모 연산자 ^

분모 연산자 ^는 어떤 수의 분수를 가져옵니다.

예를 들어 ^1/4의 연산 결과는 4가 됩니다.

만약 면발, 그릇 또는 널과 함께 분모 연산자를 사용한 경우 평가 결과는 널이 됩니다.

분모 연산자는 분수 구분자보다 낮은 우선순위를 가지기 때문에 ^1/4를 평가한 결과는 ^(1)/4 -> 1/4가 아닌 ^(1/4) -> 4와 같은 순서로 평가됩니다. 그러나 분모 연산자는 곱셈 연산자보다는 높은 우선순위를 가지므로 , ^1/3 * 1/7(^(1/3)) * (1/7)와 동일한 순서로 평가됩니다.

비교 연산자

?= 연산자

?= 연산자는 두 수가 같은지 평가합니다. 만약 두 수가 동일하다면 평가 결과는 수 1이 됩니다. 그 외의 경우에는 수 0이 됩니다.

예를 들어, 3 ?= 6의 평가 결과는 수 0 입니다. 또, 1/2 ?= 3/6의 평가 결과는 수 1이 됩니다.

만약 면발, 그릇 또는 널과 함께 ?= 연산자를 사용한 경우 평가 결과는 널이 됩니다.

> 연산자

> 연산자는 두 수 중 첫 번째 수의 크기가 두 번째 수의 크기보다 큰지 평가합니다. 만약 첫 번째 수의 크기가 두 번째 수의 크기보다 크다면 평가 결과는 수 1이, 그렇지 않다면 수 0이 됩니다.

예를 들어, 3 > 6의 평가 결과는 수 1 입니다. 또, 1 > 1의 평가 결과는 수 0이 됩니다.

만약 면발, 그릇 또는 널과 함께 > 연산자를 사용한 경우 평가 결과는 널이 됩니다.

< 연산자

< 연산자는 두 수 중 첫 번째 수의 크기가 두 번째 수의 크기보다 작은지 평가합니다. 만약 첫 번째 수의 크기가 두 번째 수의 크기보다 작다면 평가 결과는 수 1이, 그렇지 않다면 수 0이 됩니다.

예를 들어, 3 < 6의 평가 결과는 수 0 입니다. 또, 1 < 1의 평가 결과는 수 0이 됩니다.

만약 면발, 그릇 또는 널과 함께 < 연산자를 사용한 경우 평가 결과는 널이 됩니다.

논리 연산자

AND 연산자 &

AND 연산자 &는 두 수의 AND 논리 연산과 유사한 역할을 합니다. 만약 두 수 모두 0이 아니라면 평가 결과는 수 1이, 그렇지 않다면 수 0이 됩니다.

예를 들어, 0 & 0의 평가 결과는 수 0입니다. 또, 3 & 1의 평가 결과는 수 1, 2 & 0의 평가결과는 수 0이 됩니다.

만약 면발, 그릇 또는 널과 함께 AND 연산자 &를 사용한 경우 평가 결과는 널이 됩니다.

OR 연산자 |

OR 연산자 |는 두 수의 OR 논리 연산과 유사한 역할을 합니다. 만약 두 수 모두 0이라면 평가 결과는 수 0이, 그렇지 않다면 수 1이 됩니다.

예를 들어, 0 | 0의 평가 결과는 수 0입니다. 또, 3 | 1의 평가 결과는 수 1, 2 | 0의 평가결과는 수 1이 됩니다.

만약 면발, 그릇 또는 널과 함께 OR 연산자 |를 사용한 경우 평가 결과는 널이 됩니다.

NOT 연산자 !

NOT 연산자 !는 수의 NOT 논리 연산과 유사한 역할을 합니다. 만약 어떤 수가 0이라면 평가 결과는 수 1이, 그렇지 않다면 수 0이 됩니다.

예를 들어, !0의 평가 결과는 수 1입니다. 또, !3의 평가 결과는 수 0이 됩니다.

만약 면발, 그릇 또는 널과 함께 NOT 연산자 !를 사용한 경우 평가 결과는 널이 됩니다.

그릇 참조문

비빔은 : 문자를 통해 그릇이 담고 있는 면발의 내용을 참조할 수 있습니다. 이 때, : 문자 앞의 표현식은 참조할 그릇, 뒤의 표현식은 참조할 면발의 면발 번호입니다.

예를 들어 아래 코드는 세 개의 면발을 담고있는 그룻 중에서 면발 번호가 1인 면발의 내용을 평가합니다. 따라서 아래의 코드를 평가한 결과는 수 69입니다.

{
    [0; 72]
    [1; 69]
    [2; 76]
}:1

그릇 참조문은 분모 연산자보다는 높은 우선순위로 평가되지만 분수 구분자보다는 나중에 평가됩니다.

만약 그릇에 담겨있지 않는 면발 번호를 참조하려고 시도한 경우 널을 반환합니다. 또, : 문자의 앞에 사용된 표현식을 평가한 결과가 그릇이 아니거나, 뒤에 사용된 표현식을 평가한 결과가 수가 아닐 경우에도 널을 반환합니다.

그릇 대입문

비빔에서 그릇 참조문과 함께 = 문자를 사용해서 그릇에 면발을 추가하거나 면발 내용을 수정할 수 있습니다. 표현식의 형태는 <그릇>:<면발 번호> = <면발 내용>의 꼴입니다.

예를 들어 아래 코드는 세 개의 면발을 담고있는 그룻 중에서 면발 번호가 1인 면발의 내용을 72로 변경합니다.

{
    [0; 72]
    [1; 69]
    [2; 76]
}:1 = 72

대입하는 면발 내용의 표현식은 수, 그릇 또는 널을 사용할 수 있습니다. 만약 그릇에 담겨 있지 않는 면발 번호를 참조하여 그릇 대입문을 사용하는 경우, 해당 면발 번호와 대입하는 면발 내용을 가지는 새로운 면발을 그릇에 담습니다.

그릇 대입문의 평가 결과는 언제나 널입니다.

특수 그릇 @

비빔에서 @ 문자는 사전에 정의된 특수한 그릇을 나타냅니다. 이는 코드 어디에서나 접근할 수 있으며, 기존의 그릇 자료형과 동일하게 사용할 수 있습니다.

그러나 그릇 참조문 또는 그릇 대입문을 면발 번호 0과 1을 사용해서 수행할 경우 미리 정의된 특수한 동작을 수행합니다.

현재 실행중인 면발 번호 @:0

비빔에서 @:0는 현재 실행중인 면발 번호를 참조합니다.

@:0의 값은 실행시킨 그릇에 담겨있는 각 면발이 실행되기 직전에 자동으로 변경됩니다.

또, @:0에 그릇 대입문을 수행하더라도 @:0의 내용은 변경되지 않습니다.

입출력 @:1

비빔에서 @:1를 참조하여 표준 입력으로부터 문자열을 입력받고, @:1에 그릇을 대입하여 표준 출력으로 문자열을 출력합니다.

만약 @:1에 그릇 외의 값(수, 면발, 널)을 대입하는 경우 오류를 발생시키고 프로그램이 종료됩니다.

그릇과 문자열간의 변환

비빔에는 문자열을 정의하는 특별한 자료형이 없습니다. 대신 그릇을 문자열로서 사용할 수 있습니다.

만약 @:1을 참조하여 표준 입력으로부터 문자열을 받을 경우, 문자열의 각 문자를 하나씩 면발로 변환한 후 그 면발들을 담고 있는 그릇을 문자열처럼 사용합니다. 문자를 면발로 변환할 때에는 0부터 시작하는 문자의 index를 면발 번호로, 문자의 UTF-8로 인코딩된 유니코드 값을 면발 내용으로 변환됩니다.

예를 들어, 문자열 HELLO WORLD를 그릇으로 변환한 경우 아래와 같습니다.

{
    [0; 72]
    [1; 69]
    [2; 76]
    [3; 76]
    [4; 79]
    [5; 32]
    [6; 87]
    [7; 79]
    [8; 82]
    [9; 76]
    [10; 68]
}

@:1에 그릇을 대입하여 문자열을 출력할 때에도 유사한 변환 과정을 거칩니다. 단, 그릇 안에 담겨있는 면발은 면발 번호가 0인 면발의 면발 내용부터 평가하기 시작하여 이전에 확인한 면발 번호보다 1씩 큰 면발 번호를 가지는 면발의 면발 내용을 차례대로 평가하여 문자열로 변환합니다. 만약 이전에 확인한 면발 번호보다 1 큰 면발 번호를 가지는 면발을 그릇에서 찾을 수 없을 경우 문자열 변환을 마칩니다.

이 때, 평가되는 면발 내용을 문자로 변환할 수 없을 경우 에러가 발생하고 프로그램이 종료됩니다. 또, 평가되지 않는 면발 내용은 얼마든지 그릇에 담겨있어도 좋습니다.