다음 기호 예측

NZPC Speak 프로그램의 임의 지점까지 잘린 앞부분이 주어질 때, 선언과 가림 규칙 및 부분 이름을 고려하여 다음에 올 수 있는 기호를 모두 나열한다.

어려움8구현시뮬레이션스택문자열아직 제출이 없습니다시간 제한2초메모리 제한512 MB

문제

NZPC Speak 언어를 편집하는 에디터는 자동 완성 힌트를 보여 준다. 프로그램의 앞부분을 받아서 그 다음에 입력할 수 있는 기호를 모두 나열한다. 이 예측기를 작성하라.

NZPC Speak 프로그램은 다음 규칙을 따른다.

  • 프로그램은 블록 하나다.
  • 블록은 중괄호 {}로 감싼 선언과 문장의 나열이다. 나열은 비어 있어도 된다.
  • 선언은 int 또는 float 뒤에 쉼표로 구분한 이름 목록이 오고 세미콜론으로 끝난다. 이름은 하나 이상이어야 한다.
  • 문장은 블록이거나 대입문이다.
  • 대입문은 이름, =, 식이 차례로 오고 세미콜론으로 끝난다. 대입에서 타입 검사는 하지 않는다.
  • 식은 항 하나 이상을 연산자 +, -, *, /로 이은 것이다. 항은 이름이거나 정수다. 정수와 실수는 제약 없이 섞어 쓸 수 있고, 괄호는 없다.
  • 이름은 대문자와 소문자(서로 다른 문자로 본다), 숫자, 밑줄로 만든다. 이름의 첫 글자는 숫자가 아니어야 한다.
  • 정수는 숫자의 나열이다.
  • 예약어 intfloat는 이름으로 쓸 수 없다.
  • 이름은 쓰기 전에 선언되어 있어야 한다. 식 안에서 쓸 때도, 대입의 대상으로 쓸 때도 그렇다.
  • 안쪽 블록에서 선언한 이름은 선언 지점부터 그 블록을 닫는 }까지 바깥 블록의 같은 이름을 가린다. 한 블록에서 같은 이름을 두 번 선언하면 뒤쪽 선언이 그 지점부터 앞쪽 선언을 대체한다.
  • 토큰 사이에는 공백과 줄바꿈을 넣을 수 있다. intfloat 뒤에는 공백이나 줄바꿈이 적어도 하나 있어야 한다.

다음은 완성된 프로그램이다.

{
   int abc, abcd, abcdef;
   float ab, x, xy, xz;
   abc = 12 * xy + 99;
   {
       float abc;
       int xy;
       xy = abc + abcd;
   }
}

입력으로 주어지는 글은 위 규칙을 모두 지키는 프로그램의 앞부분을 임의의 글자에서 자른 것이다. 그 다음에 올 수 있는 기호를 구하라. 예측 기호는 구두점과 연산자({, }, ,, ;, =, +, -, *, /), 예약어 intfloat, 자른 지점에서 보이는 이름 중 하나다. 정수는 무한히 많으므로 예측하지 않는다.

글의 맨 끝에서 이름 문자(영문자, 숫자, 밑줄)가 이어지는 가장 긴 구간을 p라고 하자. 글이 비어 있거나 공백, 줄바꿈, 구두점으로 끝나면 p는 빈 문자열이다.

p가 빈 문자열이면 자른 지점에서 시작할 수 있는 기호를 모두 나열한다.

p가 비어 있지 않으면 사용자가 이름이나 예약어를 입력하는 중이므로 그것을 이어 갈 수 있는 기호만 나열한다. 즉 p로 시작하면서 p가 시작한 자리에서 나올 수 있는 예약어와 보이는 이름을 나열한다. 이름을 이미 끝까지 적었더라도 뒤에 글자가 더 붙을 수 있으므로 그 이름도 나열한다. 입력 중인 것이 정수면 p가 숫자로 시작하는데 숫자로 시작하는 이름과 예약어는 없으므로 아무것도 나열하지 않는다.

선언에서 새 이름을 입력하는 자리라면 p가 비어 있든 아니든 아무것도 나열하지 않는다.

입력

첫째 줄에 프로그램의 개수 T가 주어진다 (1 <= T <= 100). 이어서 프로그램이 차례로 주어진다. 각 프로그램은 1개 이상 100개 이하의 줄로 이루어지고 마지막 줄은 @로 끝난다. @는 자른 지점을 나타내며 프로그램 본문에 포함되지 않는다. 각 줄의 길이는 200자 이하다.

출력

각 프로그램마다 Problem #을 한 줄에 출력한다. #은 1부터 시작하는 프로그램 번호다. 그 다음에 예측 기호를 한 줄에 하나씩 출력한다. 정렬에 쓰는 문자 순서는 다음과 같다.

* , / ; _ { } + - = 0 1 2 3 4 5 6 7 8 9 a A b B c C d D e E f F g G h H i I j J k K l L m M n N o O p P q Q r R s S t T u U v V w W x X y Y z Z

두 기호는 이 순서로 왼쪽부터 한 글자씩 비교하고, 다른 기호의 접두사인 기호를 먼저 놓는다. 이름은 바로 뒤에 괄호로 타입을 붙여 xy(float)처럼 출력하고, 정렬에는 이름만 쓴다. 예약어와 구두점은 기호만 출력한다.