
declarations : 정의부분
token 정의, starting symbol의 키워드를 정의할수있다.
starting symbol이 없으면 처음 기술된 애를 사용.
%token - 규칙들을 정의 터미널 심볼을 정의할수있다.
규칙부분에 identifier을 쓰면 그것을 심볼로 인식한다.
이 정의는 lex에서 주어진 token이 주어지는데 이것과 일치해야한다.
first token에 반드시 담겨있어야한다.

규칙은 여러개를 동반할 수 있고
하나의 규칙은 lhs rhs action
action은 c programming 형식이다.
reduce 하는 관점에서 동시에 실행될수있는 문장.
identifier가 아닌 symbol을 정의하는 것은
expr : expr '+' expr {}
E: E plus E - plus는 무조건 token으로 정의되어 있어야 한다. token으로 정의되어 있지 않으면 nonterminal로 인식하기 때문에 문법오류 발생.
어휘분석기에서 return ('+') 같이 리턴해버리면 token 값이 아니라 ascii로 생각해버린다.
우리가 생각하는 ascii 값 이외의 것으로 token 값을 부여한다. return(plus)같이 리턴을 하게 되어야하고 이에 대한 정의는 lex도 포함하고 있어야한다.
lex가 생성해낸 lex.yy.c이 파일을 yacc 을 기술할 떄 같이 포함해서 작업되면 %token을 정의될때 동일한 식별자로 인식할 수 있다.
헤더파일을 만들어서 token 정보값을 include 해서 사용해도 된다.
lex의 토큰 넘버와 yacc의 토큰 넘버를 일치시키면 된다.
한개 문자에 대해 ascii값이 있으므로 두개문자로 이루어진 terminal symbol들은 따로 추가해야 한다.
begin같은 reserved word는 'begin'같이 정의하고 return ('begin')은 틀리다.
이럴때는 %token Tbegin으로 정의해서
reutrn (Tbegin)으로 하면 된다.





모호한 트리가 발생할거같으면 shift reduce conflict가 발생하고 일단은 shift우선으로 실행한다.
정의부분에 left associate 해달라 지정해주면 모호성이 사라진다.
%left '+' '-' 같이 써주면 왼쪽꺼 쓴다.
%nonasocciate '='를 하면 a=b=c같은 것은 없앨수있다.
topdown은 left recursive가 있으면 안되지만
bottom up은 left recursion이 있어도 된다.
왜냐하면 left associating 할수있기 때문이다.
right 면 앞의 정보를 다 stack에 쌓아놔야하기 떄문에 left를 통해서 바로 해결하는 식으로 하는 것이 효율적이다.
그래서 bottomup은 left associate 를 선호한다.

reduce reduce conflict는 거의 발생하진 않지만 발생한다면 문법을 뜯어고쳐야한다.
즉 생성규칙 순서에 따라서 정의 : 앞쪽에 있는 생성규칙을 유도하도록. 모호성있는 input이 주어질때 결정적 분석이 가능하게 reduce하도록 결과값을 얻는다.

