PS에서 표준 입출력을 자주 활용하는 만큼, 특수 문법으로 지정하여 사용합니다.
형식 입력 문법을 기본으로 하고, 나머지 문법은 논의해볼 만한 문법적 설탕입니다.
<형식 입력> = "read" <형식 지정자>
<공백 구분 입력> = "read" (<식별자> | <형식 지정자>),*
<선언과 동시에 입력> = "read" <타입> <식별자>,* // TODO: 의견 수렴
<줄 단위 입력> = // TODO
모든 입력은 형식 지정자 상태로 받는다고 가정한다. 이에, <공백 구분 입력>과 <선언과 동시에 입력>의 경우 문법적 설탕으로써, 다음과 같이 해석한다.
// 이 구문은
read a, b, ..., y, z
// 아래 구문과 같다
read `{a} {b} {...} {y} {z} `
// 이 구문은
read i32 a, b, ..., y, z
// 아래 구문과 같다
i32 a, b, ..., y, z; read `{a} {b} {...} {y} {z} `
입력에서 형식 지정자는 대략적으로 다음과 같은 과정을 걸쳐 각 토큰을 해석한다.
- 해석 후 할당 토큰:
"{" <이름> "}"
의 형태이다. 예:{a}
,{num}
- 공백 토큰:
<공백 문자>+
의 형태이다. 예:\r \t
,\r\r\n\t\n
- 문자 토큰:
<앞 규칙에 매칭되지 않은 문자>
의 형태이다. 예::
,/
- 토큰
T
가 주어진다. - 현재 버퍼에 있는 공백을 모두 지운다.
T
가 공백 토큰이라면 다음 토큰을T
에 할당하고 과정 1로 돌아간다.- EOF 여부를 확인한 후, EOF라면 EOFError를 던진다.
T
가 어떤 토큰이냐에 따라 다음과 같이 처리한다.- 해석 후 할당 토큰이라면 입력 버퍼를 읽어 이름에 할당된 타입에 맞게 파싱해 저장한다. 파싱에 실패할 경우 FormatError를 발생시킨다.
- 공백 토큰은 과정 3에 의해 등장하지 않는다.
- 문자 토큰이라면 입력 버퍼에서 문자를 읽어 정확히 일치하는지 확인한다. 일치하지 않을 경우 FormatError를 발생시킨다.
- 다음 토큰을
T
에 할당하고 과정 1로 돌아간다.
입력은 오류를 동반할 수 있기 때문에 read 표현식의 반환형은 fallible 타입이다. 이를 활용해 다음과 같은 코드를 작성할 수 있다.
// EOFError나 FormatError가 뜰 때까지 반복하기
while read `{n}` { ... }
// EOFError가 뜨면 break하는 무한 반복문
// FormatError는 처리하지 않아 throw된다
loop {
i32 n
read `{n}` catch EOFError { break }
}
형식 출력 문법을 기본으로 하고, 나머지 문법은 논의해볼 만한 문법적 설탕입니다.
<형식 출력> = "write" <형식 지정자>
<공백 구분 출력> = "write" <식별자>,* // TODO: 의견 수렴