yyerror 호출 후 exit 안하게 하기
yacc과 lex를 이용한 mini c 컴파일러 과제 수행 도중,,,
//identifier가 숫자로 시작하면 에러
[0-9][A-Za-z0-9_]+ {
// printError는 다른 스크립트의 함수인데 extern 해서 가져옴
printError(falseID);
}
lex 파일에 이런 느낌으로 커스텀 에러를 잡는 구문이 있었다.
테스트를 위해 mc 파일에 숫자로 시작하는 identifer를 넣고 lex.yy.c랑 parser.tab.c(+다른 잡다한 코드들)을 돌렸다.
근데 숫자로 시작하는 identifier을 만나면 yyerror 호출-parse error 뜨고 그냥 끝나버렸다. 그 뒤에도 계속 체크해야되는데...
//identifier가 숫자로 시작하면 에러
[0-9][A-Za-z0-9_]+ {
printError(falseID);
return(tident); //추가
}
이렇게 하면 된다. 이것때문에 반나절 날라감;;;;;;
에러용 토큰 추가하고 yacc파일에 해당 토큰 관련 코드를 추가하는 식으로도 해결할 수 있지만 그것보단 기존에 있던 ident를 활용하는게 훨씬 나은 것 같다.
yacc 파일에서 잡는 에러는 yyerrok를 쓰면 된다.
자세한 건 아래 링크 참고
https://stackoverflow.com/questions/2232968/how-to-make-bison-not-exit-when-it-calls-yyerror
How to make Bison not exit when it calls yyerror
When my parser is scanning a source file and some syntax is incorrect, and it calls yyerror, I want it to display the error message, but continue parsing the file to potentially display more errors.
stackoverflow.com
http://web.mit.edu/gnu/doc/html/bison_9.html
Bison - Error Recovery
Go to the previous, next section. It is not usually acceptable to have a program terminate on a parse error. For example, a compiler should recover sufficiently to parse the rest of the input file and check it for errors; a calculator should accept another
web.mit.edu
이렇게 해도 다양한 이유로 parse error 뜨고 죽어버릴 수도 있다. 예를 들어 나는 해쉬심볼테이블 구현하느라 yacc파일에서 이것저것 했는데, 그 과정에서 특정 상황(내 경우엔 global 변수 선언)에 null 에러가 발생해서 parse error가 뜨고 프로그램이 끝나버린적이 있다.
+
참고로 lex.yy.c에서
input 재정의 이전 정의는 데이터 변수입니다.
라는 에러가 뜬다면 헤더 include 한 부분이나 선언부에서 뭐가 꼬였을 확률이 높다.
이건 고치는게 어렵지는 않은데 조금만 삐끗해도 뜬다. 컴파일러 과제하면서 많이 본 에러 순위권일듯,,,