boost의 spirit 질문입니다.
글쓴이: lacovnk / 작성시간: 화, 2005/09/13 - 1:05오전
"sql bla"가 유효한 sql query문이라고 가정하고, "sql"은 유효하지 않다고 합시다.
sql bla;sql bla;sql bla;sql [엔터] bla;[엔터]
다음과 같이 쳤을때, 앞의 세 sql bla는 엔터를 치자 마자 처리가 되고, 마지막 것은 엔터를 친 후에 bla;를 마저 치고 엔터를 치고 난 후에 들어 올 경우 처리를 해야겠지요.
그런데, spirit에서 이를 어떻게 해야 할지 모르겠습니다 orz
들어오는 것을 buffering해서 끝의 미완성된 sql을 떼어버리고 parser에게 넘길까 하는데.. 그건 구차한 방법 같고 -o-
documentation의 어느 부분을 읽어야 할지 난감합니다;; 힌트 주세요~ :)
현재는 다음과 같이 쓰고 있습니다.
int main() { string str_in,str_buf; sql_grammar sqlg; print_prompt(); while (getline(cin, str_in)) { str_buf += str_in; parse_info<> info = parse(str_buf.c_str(),sqlg,space_p); if (false == info.full) { cout << "Parsing failed\n"; cout << "stopped at: \"" << info.stop << "\"\n"; } print_prompt(); } cout << "Bye \n\n"; return 0; }
Forums:
[quote]들어오는 것을 buffering해서 끝의 미완성된 sql
전처리하는 부분을 만드시는게 좋을 것 같습니다. 추후 확장하기도 좋을 듯 싶구요.
문제는 쪼개서 푸는게 쉽다고 생각하는지라... :wink:
또 다른 질문...
str_buf 을 두어서, 세미콜론 기준으로 파서에게 넘겨주기로 하는 걸로 임시 처방을 했습니다.
두번째, error recovery관련입니다.
http://spirit.sourceforge.net/distrib/spirit_1_8_3/libs/spirit/doc/error_handling.html
여기에 보면
으로, 에러 핸들링 함수는 scanner의 포지션을 바꿀 수 있다고 되어 있습니다.
http://spirit.sourceforge.net/distrib/spirit_1_8_3/libs/spirit/doc/indepth_the_scanner.html
여기에서,
를 이용해서, 에러가 나면 한칸씩 앞으로 가면서 파싱을 재 시도하게 만들기 위해서, 핸들러를 다음과 같이 만들었습니다.
그런데 결론은.. "asdf"라는 명령어를 주고 찍어보면,
이렇게 무한히 찍게 됩니다. 즉, 저 핸들러 함수 내에서 ++scan 한 것이 반영이 안되는 것이죠;
1. 보아하니, 핸들러 함수에서 const로 scan을 받는다 하였는데, 이게 상관이 있나요? 참조를 const로 부를 경우, 안의 내용도 바뀌지 않는 다는 것을 보장하는 것인가요? (기초질문이군요ㅠ) 그런데, 만약 불변이라면, 컴파일에서 에러를 내야 하는 것 같은데, 에러도 나지 않았습니다.
2. 분명 문서에서는 scanner의 position을 바꾼다 하였는데, 어떻게 하면 될까요?; ++scan.first 도 마찬가지의 행동을 보입니다 (어차피 operator++의 내용이 저것인지라..)
Re: 또 다른 질문...
error handling을 쓰지는 않지만 궁금해서 찾아보았습니다.
http://users.utu.fi/~sisasa/oasis/cppfaq/const-correctness.html#[18.7]
을 보시면 ScannerT const& scan는 곧 const ScannerT & scan이 되고 그렇다면 scan값을 바꿀 수 없을 것 같습니다.
에러가 안나는 이유는 compiler에 따라 달라질 수 있을 것 같습니다.
별로 도움이 되지 못한 답변이군요. :oops:
이상하네요...
g++이고, -Wall option을 줬는데 아주 멀쩡합니다. orz
spirit에서 scanner의 position을 바꾸는게 ++scan 말고 다른 방법이 있나요?
질문또..
reserved 키워드를 처리를 못하고 있습니다 -o-
이렇게 해놓고 쓰고 있는데..
select * from table
이런 코드에서 table이 TABLE로 인식이 안되고 identifier로 인식이되는지, 에러가 나지 않습니다 -o-
1. keywords는 대체 뭔가요?;; grammer를 뒤져봐도 안나오고 -o-
2. keywords를 먼지 인식하는, 해결방법은 무엇인가요?
보셨을 것 같기도 한데 이걸 참조해보시면 어떨까요?http://s
보셨을 것 같기도 한데 이걸 참조해보시면 어떨까요?
http://spirit.sourceforge.net/repository/applications/spirit_sql.zip
select 문만 구현했다고 합니다.
보았는데..
저걸 토대로 추가하고 수정하고 있는데, 저 프로그램 역시 예약어를 키워드로 받아들이지 않는 문제가 있습니다 orz
사실 keyword 같은 것 준 것도 저 소스에서 그대로.. 8)
으음. spirit을 이용한 좀더 큰 어플을 보고 싶은데, sf에는 없네요. 으음..
사용해보신 분 계신 것 같은데 경험담이라도 부탁드려요~ :)
Re: 질문또..
위 code대로라면 "table"이 identifier로 인식되는데 아무 문제가 없으니
식으로 해야 하지 않을까요?
compile이 될지 모르겠네요. 해보지 않고 올리는 거라 죄송합니다. :oops:
그렇게 하니 됩니다 ㅎㅎ
키워드를 빼주니 되는군요. 감사합니다! :)
근데 여전히 에러처리는 되지 않네요. 으음..
const를 빼도 마찬가지 입니다.(루틴 내에서는 한칸 뒤로 가는데, 찍어보면 제자리에서 retry하고 있습니다) 좀더 자세히 알아봐야겠군요.
AST 사용중에 질문입니다.
이렇게, column_name_list 이하에 column_name이 주렁주렁 달리게 하고 싶습니다
그런데, column_name_list에서, column_name이 한번만 나올 경우에는 하나만 매달리는 것이 아니라 아예 올라와버립니다.
즉,
1)은 잘 되는데, 2)으로 되어야 할 것이 3)으로 되어버려서, parent->children.size()이 0이 되어버립니다. 으으...
2번으로 하려면 어떻게 문법을 정의해야 할 까요?;;
그리고, 한 노드의 children을 다음과 같이 접근 했는데, 좀더 깔끔한 표현은 없을까요? parent->children이 vector로 관리된다고 하는데... 각각을 다음과 같이 접근 했습니다.
그런데, iterator가 아닌, 각각의 노드를 받고 싶은데, type를 뭐로 해야 할 지 모르겠습니다 orz
자문 자답!
일단, AST는 불필요한 노드를 없애버리는 성질이 있었군요 -o-
http://spirit.sourceforge.net/distrib/spirit_1_8_3/libs/spirit/doc/trees.html
main 코드에서 ast_parse를 pt_parse로 바꿔주니 잘 됩니다 ㅎ (include 잡아주고..)
댓글 달기