숫자를 가져 와서 해당 번호의 명령을 처리하는 간단한 개념 증명 응용 프로그램 (REPL)을 만들고 싶습니다.
예 : 1부터 시작합니다. 그런 다음 ” add 2
“를 쓰면 나에게 3 multiply 7
을줍니다. 그런 다음 ” “를 쓰면 나에게 21을줍니다. 그런 다음 소수인지 알고 싶어서 ” is prime
“(현재 숫자에- 21), 그것은 나에게 거짓을 준다. ” is odd
“는 저에게 사실을 줄 것입니다. 등등.
이제 명령이 적은 간단한 응용 프로그램의 switch
경우 명령을 처리 하는 간단한 작업도 수행됩니다. 그러나 확장 성을 원한다면 어떻게 기능을 구현해야합니까? 명령 패턴을 사용합니까? 언어에 대한 간단한 파서 / 인터프리터를 작성합니까? ” multiply 5 until >200
” 와 같이 더 복잡한 명령을 원하면 어떻게 합니까? 재 컴파일하지 않고 확장 (새 명령 추가)하는 쉬운 방법은 무엇입니까?
편집 : 몇 가지를 명확히하기 위해, 나의 최종 목표는 WolframAlpha와 비슷한 것이 아니라 (숫자 목록) 프로세서를 만드는 것입니다. 그러나 처음에는 천천히 시작하고 싶습니다 (단일 숫자로).
Haskell을 사용하여 목록을 처리하는 방식과 매우 비슷한 버전이지만 매우 간단한 버전을 염두에두고 있습니다. 명령 패턴 (또는 이와 동등한)과 같은 것이 충분하거나 목표를 달성하기 위해 새로운 미니 언어와 파서를 만들어야하는지 궁금합니다.
Edit2 : 모든 답변에 감사드립니다. 모두 도움이되었지만 Emmad Kareem이 가장 많이 도와 주었으므로 답변으로 선택하겠습니다. 다시 감사합니다!
답변
통역사처럼 들립니다. 자세한 기능보다 구현에 대해 걱정하는 것 같습니다 (여기서는 추측하고 있습니다). 확장 된 경우이 프로젝트는 사소한 작업이 아닙니다. 때로는 작동하는 1000 개의 패치가있는 제품이 아니라 신뢰할 수있는 제품을 얻기위한 임시 개발 방법이 아니라 엔지니어링 방법이 필요하므로 범위를 명확하게 연구해야합니다.
구문을 결정하고 구문 분석하고 필요한 구문 검사를 수행 할 수 있도록 준비하십시오. 이 링크는 다음과 같이 도움이 될 수 있습니다 . 고유 한 구문 분석기 작성 .
살펴보십시오 :이 주제는 작업의 여러 측면에 대해 다루면서 도움을 줄 수있는 좋은 링크가 있습니다 (특히 RMK의 답변) .: 언어 통역사 만들기 . Ultimate Programmable Scientific Calculator 에서 다소 비슷한 멋진 프로젝트의 예를보고 싶을 수 있습니다 . 커맨드 라인 C # 인터프리터에 대한 소스 코드 및 작업 프로그램은 C # -Made-for-Teaching 명령 줄에서 찾을 수 있습니다 . 컴파일러를 사용하여 구문 분석 및 변수 입력 등과 같은 복잡한 작업을 수행하면이 모든 것을 직접 작성하는 복잡성을 피할 수있는 영리한 방법 일 수 있습니다. 또한 CsharpRepl 에서 살펴볼 수있는 charp shell 기능을 제공하는 Mono 옵션이 있습니다 .
답변
실제 파서를 작성하는 데 특별히 관심이 없다면 파서 생성기 프레임 워크 중 하나를 살펴 보는 것이 좋습니다. C의 경우 YACC 또는 Bison 이 있지만 원하는 경우 다른 언어에 대한 다른 대안이 있어야합니다.
복잡한 문법을 분석하는 복잡성을 없애고 원하는 작업에 집중할 수 있습니다. 물론 이것은 당신이 질문에서 제안하는 문법에는 과잉 일 수 있지만 나중에 더 복잡한 문법으로 확장 할 수있는 옵션을 언급 했으므로 적어도 이러한 프레임 워크에서 영감을 얻는 것이 좋습니다.
답변
당신이 설명하는 것은 스택 언어에 매우 가깝습니다 .
예를 들어 Factor 에서 설명하는 내용은 다음과 같습니다.
1
2 +
7 *
even? not
또는 자신의 단어를 정의한 다음 사용할 수 있습니다.
: add ( x y -- sum ) + ;
: multiply ( x y -- product ) * ;
: odd? ( n -- ? ) even? not ;
이러한 정의로 위의 예는
1
2 add
7 multiply
odd?
일반적으로 스택 언어는 공백으로 구분 된 단일 단어를 사용하므로 구문 분석하기가 쉽지 않습니다. 나는 당신이 Factor를 살펴볼 것을 제안합니다. 필요한 처리를 수행하는 단어를 쉽게 정의 할 수 있어야합니다.
편집 : 실제로 비슷한 언어를 디자인하려면 어쨌든 그중 하나를 가지고 노는 것이 좋습니다. 스택 언어를 파싱하는 것은 쉬운 일이 아닙니다. 빈 공간을 분할하고 순진한 처리 구현이 쉽습니다. 스택에서 발생하는 일을 처리하면됩니다.
답변
그러나 확장 성을 원한다면 어떻게 기능을 구현해야합니까?
해서는 안됩니다. 확장 성은 매우 적은 이득을 위해 많은 복잡성을 만듭니다. 즉, 기존 상태에 대한 후크를 제공해야합니다. 상태를보고, 상태를 수정하고, 다른 결과를 화면에 표시하는 메커니즘을 제공하는 방법입니다. 핵심 코드가 모듈을 발견하고로드하고 명령을 전달할 수있는 방법이 필요합니다.
명령 패턴을 사용합니까?
할 수는 있지만 적절하지 않을 수 있습니다.
전체 입력을 가져 와서 처리를 위해 보내지 않고 입력을 구문 분석하고 올바른 처리기로 전달하여 작업을 수행하도록하십시오. 그 의사 소통은 그 의사 소통에서 변하지 않습니다. 명령 패턴이 없습니다.
언어에 대한 간단한 파서 / 인터프리터를 작성합니까?
입력을 토큰으로 나누는 것을 처리 할 무언가가 필요합니다. 확장 가능한 솔루션의 경우 더 많은 작업을 수행하지 않을 것입니다. 올바르게 정의 된 솔루션의 경우 전체 구문 분석 트리를 사용하면 성능, 오류 처리 및 디버그 기능이 향상됩니다.
오히려 (수) 프로세서 목록
그렇다면 LISt Processing 언어를 살펴 봐야 할 것 입니다. 코드와 데이터의 병치가 설명하는 내용과 잘 맞아야합니다.