문제

몇 가지 질문에서 나는 권장 사항을 보았습니다 영혼 Parser-Generator 프레임 워크 boost.org, 그러나 그 의견에는 행복하지 않은 정신을 사용하는 사람들로부터 불평이 있습니다. 그 사람들이 서서 나머지 사람들에게 정신을 사용하는 단점이나 단점이 무엇인지 설명 하시겠습니까?

도움이 되었습니까?

해결책

그것은 아주 멋진 아이디어이며, 나는 그것을 좋아했습니다. C ++ 템플릿을 사용하는 방법을 실제로 배우는 것이 특히 유용했습니다.

그러나 그들의 문서는 중소형 파서에 대한 정신의 사용을 권장합니다. 전체 언어를위한 파서는 컴파일하는 데 시간이 걸립니다. 세 가지 이유를 나열하겠습니다.

  • 스캐너가없는 구문 분석. 상당히 간단하지만 역 추적이 필요할 때 구문 분석기 속도가 느려질 수 있습니다. 그러나 선택 사항입니다. Lexer는 통합 될 수 있습니다. Spure와 함께 제작 된 C 전 처리기를 참조하십시오. ~ 300 줄 (.H 및 .CPP 파일 포함)의 문법은 GCC를 사용하여 6m 파일로 컴파일합니다 (최적화되지 않음). 인라인 및 최대 최적화는이를 ~ 1,7m로 줄입니다.

  • 느린 구문 분석 - 문법을 정적으로 점검하지 않으며, 과도한 룩보드에 대한 힌트를 힌트하거나 왼쪽 재귀 사용과 같은 기본 오류를 확인할 수는 없습니다 (이는 재귀 살포 구문 분석기 LL 문법에서 무한 재귀를 초래합니다). 왼쪽 재귀는 실제로 추적하기 어려운 버그는 아니지만 과도한 전망대는 지수 구문 분석 시간을 유발할 수 있습니다.

  • 무거운 템플릿 사용 - 이것은 특정 장점이 있지만 컴파일 시간과 코드 크기에 영향을 미칩니다. 또한 문법 정의는 일반적으로 다른 모든 사용자에게 볼 수 있어야하므로 더 많은 컴파일 시간에 영향을 미칩니다. 올바른 매개 변수와 함께 명시 적 템플릿 인스턴스화를 추가하여 문법을 .CPP 파일로 이동할 수 있었지만 쉽지 않았습니다.

업데이트 : 내 응답은 Spirit V2가 아닌 Spirit Classic에 대한 나의 경험으로 제한됩니다. 나는 여전히 정신이 템플릿 기반이 될 것으로 기대하지만 이제는 추측하고 있습니다.

다른 팁

Boost 1.41에서 새로운 버전의 Spirit이 출시되고 있으며 Spirit :: Classic :

베타에서 오랜 시간이 지난 후 (Spirit 2.0의 2 년 이상) Spirit 2.1은 마침내 곧 출시 될 Boost 1.41 릴리스로 출시 될 예정입니다. 코드는 현재 매우 안정적이며 생산 코드에 대비할 준비가되었습니다. 우리는 Boost 1.41의 시간에 문서를 마무리하기 위해 열심히 노력하고 있습니다. 여기에서 문서의 현재 상태를 살펴볼 수 있습니다. 현재 Boost SVN 트렁크에서 코드 및 문서를 찾을 수 있습니다. Spirit과 관련된 새로운 프로젝트가 있다면 Spirit 2.1부터 시작하는 것이 좋습니다. Spirit Mailing List에서 Overminddl의 게시물을 인용 할 수 있습니다.

나는 이것을 얼마나 자주 말하는지 봇처럼 들리기 시작할 수 있지만 spirit.classic은 고대입니다. Spirit2.1로 전환해야합니다. 더 빠르게. 예를 들어, Spirit2.1은 전체 AST 인라인, 이상한 우선적, 나중에 물건을 구축 할 필요가 없으며 등장 할 필요가 없습니다. 당신은 정말로 업데이트해야합니다. 과거의 다른 게시물을보고 문서에 대한 링크 등 Spirit2.1을 참조하십시오 .1. Spirit2.1은 현재 Boost 트렁크에 있지만 Boost 1.41로 공식적으로 출시되지만 그렇지 않으면 완료됩니다.

저에게 가장 큰 문제는 컴파일러 나 디버거가 보시는 정신의 표현이 다소 길다는 것입니다 (아래에 복사 한 것입니다. 따로 Spirit Classic의 하나의 표현). 이 표현은 나를 놀라게합니다. Spirit을 사용하는 프로그램에서 작업 할 때 Valgrind를 사용하거나 GDB에서 Backthrace를 인쇄하는 것이 두렵습니다.

boost::spirit::classic::parser_result<boost::spirit::classic::action<boost::spirit::classic::sequence<boost::spirit::classic::action<boost::spirit::classic::action<optional_suffix_parser<char const*>, boost::spirit::classic::ref_actor<std::vector<std::string, std::allocator<std::string> >, boost::spirit::classic::clear_action> >, boost::spirit::classic::ref_actor<std::vector<int, std::allocator<int> >, boost::spirit::classic::clear_action> >, boost::spirit::classic::sequence<boost::spirit::classic::alternative<boost::spirit::classic::alternative<boost::spirit::classic::action<boost::spirit::classic::contiguous<boost::spirit::classic::sequence<boost::spirit::classic::alternative<boost::spirit::classic::chlit<char>, boost::spirit::classic::chlit<char> >, boost::spirit::classic::positive<boost::spirit::classic::alternative<boost::spirit::classic::alternative<boost::spirit::classic::alnum_parser, boost::spirit::classic::chlit<char> >, boost::spirit::classic::chlit<char> > > > >, boost::spirit::classic::ref_value_actor<std::vector<std::string, std::allocator<std::string> >, boost::spirit::classic::push_back_action> >, boost::spirit::classic::action<boost::spirit::classic::rule<boost::spirit::classic::scanner<char const*, boost::spirit::classic::scanner_policies<boost::spirit::classic::skipper_iteration_policy<boost::spirit::classic::iteration_policy>, boost::spirit::classic::match_policy, boost::spirit::classic::action_policy> >, boost::spirit::classic::nil_t, boost::spirit::classic::nil_t>, boost::spirit::classic::ref_const_ref_actor<std::vector<std::string, std::allocator<std::string> >, std::string, boost::spirit::classic::push_back_action> > >, boost::spirit::classic::contiguous<boost::spirit::classic::sequence<boost::spirit::classic::chlit<char>, boost::spirit::classic::action<boost::spirit::classic::uint_parser<unsigned int, 10, 1u, -1>, boost::spirit::classic::ref_value_actor<std::vector<int, std::allocator<int> >, boost::spirit::classic::push_back_action> > > > >, boost::spirit::classic::kleene_star<boost::spirit::classic::sequence<boost::spirit::classic::chlit<char>, boost::spirit::classic::alternative<boost::spirit::classic::alternative<boost::spirit::classic::action<boost::spirit::classic::contiguous<boost::spirit::classic::sequence<boost::spirit::classic::alternative<boost::spirit::classic::chlit<char>, boost::spirit::classic::chlit<char> >, boost::spirit::classic::positive<boost::spirit::classic::alternative<boost::spirit::classic::alternative<boost::spirit::classic::alnum_parser, boost::spirit::classic::chlit<char> >, boost::spirit::classic::chlit<char> > > > >, boost::spirit::classic::ref_value_actor<std::vector<std::string, std::allocator<std::string> >, boost::spirit::classic::push_back_action> >, boost::spirit::classic::action<boost::spirit::classic::rule<boost::spirit::classic::scanner<char const*, boost::spirit::classic::scanner_policies<boost::spirit::classic::skipper_iteration_policy<boost::spirit::classic::iteration_policy>, boost::spirit::classic::match_policy, boost::spirit::classic::action_policy> >, boost::spirit::classic::nil_t, boost::spirit::classic::nil_t>, boost::spirit::classic::ref_const_ref_actor<std::vector<std::string, std::allocator<std::string> >, std::string, boost::spirit::classic::push_back_action> > >, boost::spirit::classic::contiguous<boost::spirit::classic::sequence<boost::spirit::classic::chlit<char>, boost::spirit::classic::action<boost::spirit::classic::uint_parser<unsigned int, 10, 1u, -1>, boost::spirit::classic::ref_value_actor<std::vector<int, std::allocator<int> >, boost::spirit::classic::push_back_action> > > > > > > > >, void () (char const, char const*)>, boost::spirit::classic::scanner<char const*, boost::spirit::classic::scanner_policies<boost::spirit::classic::skipper_iteration_policy<boost::spirit::classic::iteration_policy>, boost::spirit::classic::match_policy, boost::spirit::classic::action_policy> > >::type boost::spirit::classic::action<boost::spirit::classic::sequence<boost::spirit::classic::action<boost::spirit::classic::action<

내가 좋아하지 않는 것은 다음과 같습니다.

  • 문서는 제한되어 있습니다. "Everything"이 설명되는 하나의 큰 웹 페이지가 있지만 현재 설명에는 세부 사항이 부족합니다.

  • 불쌍한 AST 세대. AST는 잘 설명되지 않았으며 AST 수정자가 작동하는 방식을 이해하기 위해 벽에 머리를 때린 후에도 AST를 쉽게 조작하기가 어렵습니다 (즉, 문제 영역에 잘 매핑하는 것).

  • "중간"크기의 문법에 대해서도 편집 시간이 엄청나게 증가합니다.

  • 구문은 너무 헤비급입니다. C/C ++에서는 코드를 복제해야한다는 사실입니다 (즉, 선언과 정의 사이). 그러나 Boost :: Spirit에서 문법을 선언 할 때 <>를 선포 할 때는 3 번 반복해야합니다. D (ASTS를 원할 때, 내가 원하는 것 : D)

이 외에는 C ++의 한계를 감안할 때 구문 분석기에서 꽤 잘했다고 생각합니다. 그러나 나는 그들이 더 개선해야한다고 생각합니다. 역사 페이지는 현재의 "정적"정신 앞에 "역동적 인"정신이 있다고 설명합니다. 나는 얼마나 빠르고 얼마나 더 나은 구문이 있었는지 궁금합니다.

가장 큰 문제는 진단이 없거나 문법 문제에 대한 다른 도움이 있다는 것입니다. 당신의 문법이 모호하다면, 파서는 당신이 기대하는 것을 구문 분석하지 않을 수 있으며, 그것을 알아 차리는 좋은 방법은 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top