if ()의 지연 평가를 구현하는 방법


10

현재 다음을 기반으로 식 평가 기 (수식과 같은 단일 줄 식)를 구현하고 있습니다.

  • 입력 된 표현식은 리터럴 부울, 정수, 소수, 문자열, 함수, 식별자 (변수)를 구분하기 위해 토큰 화됩니다.
  • 나는 괄호를 없애고 접미사 순서로 적절한 우선 순위를 가진 연산자를 정렬하기 위해 Shunting-yard 알고리즘 (가변 수의 인수로 함수를 처리하도록 약간 수정 됨)을 구현했습니다.
  • 내 션트 야드는 단순히 (시뮬레이션 된) 토큰 대기열을 생성합니다 (배열을 통해 Powerbuilder Classic 언어는 객체를 정의 할 수 있지만 동적 배열 만 기본 스토리지-실제 목록이 아니라 사전이 아님). 간단한 스택 머신

평가자가 훌륭하게 작동하고 있지만 여전히 누락되어 if()있으며 진행 방법이 궁금합니다.

션트 야드 postfixed 및 스택 기반 평가에서 if()true 및 false 부분을 가진 다른 함수로 추가 하면 하나의 if(true, msgbox("ok"), msgbox("not ok"))메시지 만 표시하면서 하나의 메시지 만 표시합니다. 함수를 평가해야 할 때 모든 인수가 이미 평가되어 스택에 배치 되었기 때문입니다.

if()게으른 방식으로 구현하는 방법을 알려주시겠습니까 ?

나는 이것을 일종의 매크로로 처리하는 것에 대해하지만 초기에는 아직 상태 평가를하지 못했습니다. 아마도 조건과 true / false 표현식을 별도로 유지하려면 대기열 이외의 다른 종류의 구조를 사용해야합니까? 지금은 표현식이 평가 전에 파싱되지만 나중에 중간 평가를 미리 평가할 수있는 사전 컴파일 된 표현식으로 저장할 계획입니다.

편집 : 문제에 대한 몇 가지 후에, 나는 내 표현의 트리 표현을 만들 수 있다고 생각합니다 (선형 토큰 스트림 대신 AST) if(). 내에서 하나 또는 다른 분기를 쉽게 무시할 수 있습니다 .

답변:


9

여기에는 두 가지 옵션이 있습니다.

1) if함수로 구현하지 마십시오 . 특수 의미 체계를 갖춘 언어 기능으로 만드십시오. 모든 것이 기능이되기를 원한다면 쉬운 일이지만 "순수한"것은 적습니다.

2) "이름 별 호출"시맨틱을 구현하면 훨씬 더 복잡하지만 if언어 요소 대신 함수로 유지하면서 컴파일러 매직이 지연 평가 문제를 처리 할 수 있습니다. 다음과 같이 진행됩니다.

if"이름으로"선언되는 두 개의 매개 변수를 취하는 함수입니다. 컴파일러가 이름 별 매개 변수에 무언가를 전달하는 것을 발견하면 생성 될 코드를 변경합니다. 표현식을 평가하고 값을 전달하는 대신 표현식을 평가하고 대신 전달하는 클로저를 작성합니다. 함수 내에서 by-name 매개 변수를 호출 할 때 컴파일러는 코드를 생성하여 클로저를 평가합니다.


확실하지 않지만 "클로저"는 "썽크"여야합니까? 흠. 방금 wikipedia 페이지를 보았습니다. "썽 크는 매개 변수가없는 클로저입니다."

"이름으로 전화하기"라고 말할 때 전 세계적으로 말하는 것입니까? 전역 이름 별 호출 대신 클로저 유형을 구현하는 경우 if 함수는 3 개의 클로저를 취하고 2 개 (조건 및 기타)를 평가하지만 모든 것이 전체 콜 바이 바이와 같은 클로저로 인식 될 필요는 없습니다. 이름 의미론
Jimmy Hoffa

@Matt : "썽크"라는 용어는 프로그래밍의 맥락에서 몇 가지 다른 것을 의미 할 수 있으며 "매개 변수없는 클로저"는 내가들을 때 가장 먼저 생각하는 것이 아닙니다. "클로저"는 훨씬 더 분명합니다.
메이슨 휠러

1
@JimmyHoffa : "이름으로 전화"라고 말할 때, 함수 인수를 설정하는 특정 스타일을 언급하고 있습니다. 많은 기존 언어와 마찬가지로 값 또는 참조 기준으로 매개 변수를 전달하도록 선택할 수있는 것처럼이 시나리오에서는 이름으로 전달하도록 선택해야합니다.
메이슨 휠러

"이름으로 호출"시맨틱에 대한 당신의 제안이 저에게 흥미로운 점을 보여 주었지만, 함수 호출이 한 줄이기 때문에 (MS-excel 공식에 대해 생각하면) 완전한 컴파일러가 아닌 평가자에게는 약간 과잉입니다. 호출 대기열을 추론하기 위해 스택의 의사 평가를 수행하여 토큰을 대기열에 넣은 후에 단계를 추가 할 수 있다고 생각합니다. 나무에서 가지를 버리는 것이 더 쉬울 것입니다.
Seki

3

서명이있는 함수 대신 :

object if(bool, object, object)

서명을 해주세요 :

object if(bool, object function(), object function())

그러면 if함수는 조건에 따라 적절한 함수를 호출하고 그 중 하나만 평가합니다.


1

모든 것을 느리게 컴파일하면 매우 쉽습니다. 값이 이미 평가되었는지 또는 더 많은 설명이 필요한지 확인할 수단이 있어야합니다.

그런 다음 다음을 수행 할 수 있습니다. 리터럴 또는 변수 인 경우 (예 : 함수 이름?) 함수를 스택에 밀어 넣습니다. 함수의 응용 프로그램 인 경우 별도로 컴파일하고 스택의 진입 점을 밀어 넣습니다.

그런 다음 프로그램의 실행은 스택의 상단이 평가 될 때까지만 반복되며 기능이 아닙니다. 평가되지 않거나 함수가 아닌 경우 스택의 상단이 가리키는 코드를 호출하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.