1

저는 재미있는 언어 같은 자바 스크립트 용 컴파일러를 작성하고 있습니다. 일명 나는 바퀴에 대해 배우기 때문에 나는 하나를 만들어서 모든 것을 찾으려고 노력하지만 이제는 붙어있다.메서드 호출을 후위 표기법으로 변환하는 방법은 무엇입니까?

간단한 접이식 표현을 구문 분석 할 때 shunting yard 알고리즘이 좋은 것으로 알고 있습니다. 접두어와 후위 연산자에 대해서도이 알고리즘을 확장하는 방법과 간단한 함수를 파싱 할 수있는 방법을 알아 냈습니다. 예를 들어

는 : 2 3 <G> 3 5 a() * + <G> 3 5 b() +

(<G> 그것이 리턴 어드레스 등 ()를 저장할 스택에 푸시 가드 토큰 스택의 상단에 함수를 호출하는 호출 명령이다으로 2+3*a(3,5)+b(3,5) 돈다 인자가 필요한만큼 튀어 나오고 리턴 할 때 결과를 푸시 백합니다.)

함수 이름이 단지 하나의 토큰 일 경우, 괄호 바로 뒤에 함수 기호로 표시 할 수 있습니다. 프로세스 중에 함수 심볼을 발견하면 연산자 스택에 푸시하고 매개 변수 변환이 끝나면 팝업합니다.

지금까지 작동 중입니다.

그러나 멤버 함수를 사용하는 옵션을 추가하면 . 연산자가 사용됩니다. 상황이 더 까다로워집니다. 예를 들어, 변환하고 싶습니다 a.b.c(12)+d.e.f(34)a.b.cd.e.f이 함수이므로 c 및 f를 함수로 표시 할 수 없습니다. 이런 식으로 파서를 시작하면 결과는 a b . <G> 12 c() . d e . <G> 34 f() .입니다. 분명히 잘못되었습니다. <G> 12 a b . c .() <G> 34 d e . f.()이 올바른 것으로 나타납니다. 그러나 괄호를 추가하면 저주의 일을 더 복잡하게 만들 수 있습니다 : (a.b.c)(). 또는 다시 호출 할 함수를 반환하는 함수를 만듭니다. f(a,b)(c,d).

이러한 까다로운 상황을 처리하는 쉬운 방법이 있습니까?

답변

0

접근 방법의 문제는 객체와 그 구성원을 .으로 구분 된 두 개의 개별 토큰으로 처리한다는 것입니다. Classical Shunting yard 알고리즘은 OOP에 대해 아무것도 모르고 있으며 함수 호출을위한 단일 토큰에 의존합니다. 따라서 문제를 해결하는 첫 번째 방법은 객체 구성원 호출에 하나의 토큰을 사용하는 것입니다. 즉 전체 a.b.c은 단일 토큰이어야합니다.

또한 자동 파서 생성기를 참조하여 문제를 해결할 수도 있습니다. 그들은 타겟 언어 (자바 스크립트)의 완전한 문법을 ​​정식 규칙의 집합으로 정의하고 파서를 자동으로 생성 할 수 있습니다. 자주 사용되는 도구 목록에는 다양한 프로그래밍 언어로 파서를 생성하는 도구가 포함되어 있습니다 : ANTLR, Bison + Lex, Lemon + Ragel. --artem

+1

'.'은 하나의 토큰과'+'만큼의 연산자입니다. – delnan

+0

@delnan이 옳습니다. 일반 연산자처럼 점을 처리해야합니다. – mahdix

0


은 (내가. 내가 자신을 해결책을 발견했다.이 질문은 아직 살아 본)

우선 위협 (...)[...] 표현을 하나의 토큰으로하고 (이를 확장 재귀 적으로). 그런 다음 함수 호출과 배열 첨자를 감지합니다. 괄호로 묶은 토큰 앞에 중위 연산자가 없으면 함수 호출 또는 배열 첨자이므로 특수 호출 함수 또는 액세스 연산자를 삽입합니다. 이 수정으로 매력처럼 작동합니다.

관련 문제