CodingWithoutComments
그는 물었다 12년 전
26

평가 및 트리별 걷는 표현식에서는 사용하여 다형성? (ala 스티브야 이제)

오늘 아침, 그냥 판독값 스티브야 Yegge& # 39, s: 다형성 실패할 때, 언제 왔는지 그의 동료 허락을 받도록 하는 질문을 통해 잠재적인 제공하십시오 인터뷰 때 그 때 http://support. 아마존.

&gt. 예를 들어 다형성의 &gt. # 39 의 기본 let& 작업을 살펴보겠습니다. &gt. &quot eval"; 같이 있는 인터뷰 질문 &gt. 나 지금까지 그러니까말이야) 는 아마존 &gt. 론씨 의해 청취했다. 문제는 &gt. 공략하고 있기 때문에 상당히 부유하도다 하나, &gt. 다양한 중요한 선택기를 &gt. 기술: OOP 설계, 반복, 이진 &gt. 나무, 다형성 및 런타임 &gt. 일반적인 경우, 입력, 코딩 인력 및 &gt. you want to make it 추가 하드) &gt. 파싱 이론. &gt. &gt. 어느 시점에서 후보 있기를 바랍니다 &gt. 보유하고 있는 수 있는 것입니다 &gt. 표현으로 이항 연산 &gt. # 39 만 사용하는 경우, re you& 트리에서만 &gt. ";;; - &quot &quot +&quot 같은 이항 연산자 &gt. ,, &quot *&quot &quot /&quot. 리프 노드 모두 &gt. 숫자, 내부 노드는 &gt. 모든 연산자. 현재 이 &gt. 표현식에서는 나무를요 걷는 것을 의미합니다. 만약 &gt. # 39 이 후보 doesn& 실현할 수 없다. &gt. 이 경우, 또는 가볍게 그들을 이끌 수 있습니다. &gt. 그들에게 필요한 한 말씀. &gt. &gt. # 39 에 있는 경우에도 여전히 그들을 it& 떠날려하면 &gt. 흥미로운 문제입니다. &gt. &gt. 이는 상반기 질문 &gt. 어떤 사람들은 (이름이 내아기마저도 &gt. 그러나 그들의 보호 죽어가는 숨을 내 &gt. 이니셜 오른길로 william Lewis) 는 느낌 &gt. 전화하고 싶으면 는작업 요구 사항 &gt. 개발자 및 직장에서 교도관님도요 &gt. 아마존, 실제로는 좀 어렵습니다. 이 &gt. 하는 것입니다. how do you go 에서 &gt. (예를 들어 있는 산술 표현식에서는 &gt. 문자열) + (2), 2 등 &quot &quot. 충족되었으며 &gt. 표현식에서는 진단트리 우리가 가지고 형용사 &gt. 이 질문에 대한 도전 일정 &gt. 점. &gt. &gt. 하반기 입니다. s # 39 이것은 let& 말하도다. &gt. a 2 인 프로젝트, 파트너, &gt. # 39, ll call &quot Willie&quot, 누가 we& 있다. &gt. 혁신을 위한 맡게 된다. &gt. 구체화하십시오 표현식에서는 붙여넣습니다 진단트리 확보하십시오 &gt. 손쉽게 부품: 결정해야 합니다. &gt. 윌리 는 클래스뿐만 chunghwa 는 &gt. 트리는. 할 수 있어 믿지아니하며 &gt. 그러나, 언어, 하나 집어 들게 합니다 &gt. (william 불지옥으 너회가 조립품을 전달하십시오. &gt. 언어. # 39 의 경우, 그 느낌이 상스러운 he& &gt. 없는 프로세서일 되리 &gt. 더 이상 프로덕션에서 제작했다. &gt. &gt. # 39 you& 수 많은 후보가 어떻게 com/go/learn_fl_tutorials_kr 놀랐습니다; d &gt. 보프 이겁니다. &gt. &gt. 야, 그러나 내가 won& # 39, t give away &gt. 部门从 나쁜거라 솔루션을 사용하는 표준 &gt. 스위치 또는 경우 스테망 (스피커에만 &gt. 그런 좋은 ifs 계층화할). A &gt. 조금 더 나은 솔루션이 部门从 &gt. 함수 포인터를 사용하여 테이블을 &gt. 그리고 아마도 최선의 해결책이 &gt. 다형성 사용해야 합니다. 난 &gt. 이를 통해 것을 권장하십시오 작업할 수 있습니다 &gt. 언젠가는. 즐거운 것!

따라서 모든 문제를 해결을 위해 시도하시겠습니까 let& # 39 의 세 가지 방법. How do you go 에서 산술 표현식에서는 &quot, 2 등 (예를 들어 있는 문자열) + (2) &quot. # 39 의, 함수 포인터를 사용하는 트리별 충족되었으며 표현식에서는 cascaded-if& 테이블 및 / 또는 다형성?

1, 2 또는 3 개의 모든 문제를 다루기 위해 알려 주시기 바랍니다.

[업데이트: 그동안 대부분 더욱 잘 맞는 직무명 수정되었음 어떤 답을.]

serdarsenay
그는 7년 전 댓글을 달았습니다
0

39 라고 나는 기록되었으므로 Harrisson& 표시하시겠습니까 기반으로 php 의 구현

답변 16 개

다형 진단트리는 파이썬 버전을 걷는 ,

#!/usr/bin/python

class Node:
    """base class, you should not process one of these"""
    def process(self):
        raise('you should not be processing a node')

class BinaryNode(Node):
    """base class for binary nodes"""
    def __init__(self, _left, _right):
        self.left = _left
        self.right = _right
    def process(self):
        raise('you should not be processing a binarynode')

class Plus(BinaryNode):
    def process(self):
        return self.left.process() + self.right.process()

class Minus(BinaryNode):
    def process(self):
        return self.left.process() - self.right.process()

class Mul(BinaryNode):
    def process(self):
        return self.left.process() * self.right.process()

class Div(BinaryNode):
    def process(self):
        return self.left.process() / self.right.process()

class Num(Node):
    def __init__(self, _value):
        self.value = _value
    def process(self):
        return self.value

def demo(n):
    print n.process()

demo(Num(2))                                       # 2
demo(Plus(Num(2),Num(5)))                          # 2 + 3
demo(Plus(Mul(Num(2),Num(3)),Div(Num(10),Num(5)))) # (2 * 3) + (10 / 2)

이진 트리를 구성자를 구축을 통해 테스트를 불과합니다.

프로그램 구조:

추상 기본 클래스: 노드입니다

  • 모든 노드입니다 상속됩니다 이 클래스

추상 기본 클래스: 비나리노데

  • 모든 이항 연산자 상속됩니다 이 클래스 그 뒤 작품을 에바루팅 표현식에서는 공정방식에 높여줍니까 -

이진 작동자 클래스: 더하기, 빼기, Mul, Div

  • 두 개의 자식 노드를 왼쪽 측면 및 오른쪽면 서브엑스프레시언스 하나씩

번호 클래스: Num

  • 숫자 값을 모두 17 42tb 리프 노드 있다 (예:
Mark Harrison
ReaperUnreal
그는 12년 전 댓글을 달았습니다
0

이 대답은 무섭게 오버 설계. 질문 2 + (2) 이 아닌 임의의 산술 계산 있었다. 또한 이 그냥 실행하므로 나무를요 얻게된다면 doesn& # 39, t 구축.

Thomas Owens
그는 12년 전 댓글을 달았습니다
12

(2) 는 산술 계산 같은 질문에 대한 계산이 아닌 2 + 2 + (2). 따라서 이 질문에 답을 하지 않지만, it& # 39 의 오버 설계 의도한 대로.

Guge
그는 12년 전 댓글을 달았습니다
1

이 질문에 답이 없는 &quot, How do you go 에서 산술 표현식에서는 &quot, 2 등 (예를 들어 있는 문자열) + (2) ". 어디에서 &quot, 데모 (플러스 (Mul (Num (2), Num (3)), Div (Num (10), Num (5)))) &quot. come from? # 39, 우리가 볼 수 있는 다른 프로그램을 don& 수 없다? 그 이유는 선택함 최대한 답변?

vanja.
그는 11년 전 댓글을 달았습니다
3

&quot, 확보하십시오 쉽냐구요 부품: 윌리 는 클래스뿐만 chunghwa 나무를요 with.&quot 결정해야 합니다.

노드보다 나타내는

우리는 둘 다 포함할 경우 괄호 5 종류의 노드입니다:

  • 바이너리 노드입니다: 마이너스 Mul Div&lt 추가, 이 두 자녀, 왼쪽 및 오른쪽 br&gt 있다.

  • \ / 노드입니다 노드입니다

  • 노드입니다 값을 가질 예정이다. , 그냥 수치값으로 노드입니다 val&lt br&gt 자녀는 없다.

  • 노드입니다 추적할 수 있도록 괄호: 자식 노드의 서브엑스프레시온, 하나의 br&gt paren&lt.

()

노드입니다

다형 솔루션에 대한 이 같은 클래스 관계를 갖고 있어야 한다.

  • 노드입니다
  • 비나리노데: 상속됩니다 노드입니다
  • 또한: 이진 노드입니다 상속됩니다
  • 마이너스. 이진 노드입니다 상속됩니다
  • Mul: 이진 노드입니다 상속됩니다
  • Div. 이진 노드입니다 상속됩니다
  • 가치: 상속됩니다 노드입니다
  • 괄호: 상속됩니다 노드입니다

모든 노드에 대해 eval () 라는 가상 함수 있습니다. 그, 그렇지 않을 경우 해당 함수 값을 되돌려줍니다 전화하시기 서브엑스프레시온.

Jonas Kongslund
그는 12년 전 댓글을 달았습니다
2

괄호 안에 포함되어 있는 추상 구문 트리 마다할 이유가 없다.

Mark Harrison
그는 5년 전 댓글을 달았습니다
0

경우도 있다. 할 수 있는 도구를 사용하지 않고, 기존 표현식에서는 재작성할 / 재생성합니다 빼냅니다 최적화합니다 중복을 최초의 표현식입니다. 물론 표현식에서는 및 평가 받고 있는 경우는 you& 오토메이티드 # 39, re 정확하다.

이 같은 이론을 얻을 수 있는 로 구문 분석 / 컴파일러와의 래빗 홀. [The Dragon 책] [1] 은 표준 텍스트 신청한 컴파일러 구조, 극한의 이렇게 오래 걸립니다. 이 예에서는 운영까지도 chunghwa 한 [문맥 자유 문법] [2] 의 기본 연산, 사용할 수 있는 문법을 파싱할 아웃해야 ui_policytable_java_spe_policy 추상 구문 트리. 그런 다음 나무를요 반복할 수 있으므로 it from the bottom up (it& # 39 의 이 시점에서 you& # 39; d 적용하십시오 다형성 / 기능 pointers/switch 줄이기 위해 기술서임을 나무를요).

39, ve i& 찾을 수 있는 [이러한 노트] [4] 믿을 수 없을 정도로 도움됐네 컴파일러와의 및 파싱 이론.

[1]: http://en.wikipedia.org/wiki/Compilers :_principles _and_tools _techniques, [2]: http://en.wikipedia.org/wiki/Context-free_grammar # Example_3

[4]: # 유라유라테이코쿠 morin/teaching/3002/ ~ http://cg.scs.carleton.ca/

ReaperUnreal
그는 12년 전 댓글을 달았습니다
0

39 의 here& 최소 CFG 의 원래 질문:

S - &gt. N N - &gt. 2 N - &gt. N O N - &gt. (N) O - &gt. - N

&gt. 이 문제를 분석할 필요가 없는 것 같아요, 그들은 도래하도록하려하는 페헤나지스 이진 작동자? 이제 우리도 시행하십시오 하나로 평가되는 토큰인지, (2) 2?

39 를 괄호 don&, t need to show up in the 표현식에서는 트리에서만 하지만 그들은 그 형태가 영향을 줍니다. E. g., 트리를 다르다 (1+2) +3 1+ (2+3):

    +
   / \
  +   3
 / \
1   2

대對

    +
   / \
  1   +
     / \
    2   3

괄호 () 는 &quot hint"; (예를 들면, 당 위해 재귀적으로 descend&quot superjoe30 ";) 를 파서

Hm. 하향식 구문 분석 없이, t think you can i don& # 39 쓰기 때문에 일부 일종의 shift+ctrl 줄일 수 있습니다. 파서 엔드입니다 퇴각검색 수 있다. LR (1) 는 물론 심지어 라라 작동합니까 그냥 그랬다고 다음 (ad-hoc) 언어 정의:

시작 - &gt. E1 &lt br>; E1 - &gt. E1 + E1 e1 e1 &lt br>; E1 - &gt. 2*E2 e2/e2 E2 &lt br>; E2 - &gt. 번호 (e1) *

E1 과 E2 를 구분하는 아웃해야 유지하는 데 필요하다고 우선순위를 * 및 / over +와 -.

하지만 이건 내가 어떻게 그렇게 했다면 파서를 직접 쓸 수 있을 것 "이라고 말했다.

  • 2 로 저장하는 스택, 트리의 노드 한 연산자를 저장 및 원-부트 피연산자로
  • 읽을 수 있는 번호 입력 왼쪽에서 오른쪽, 리프 노드 및 누름식 스택할 피연산자 묶습니다.
  • &Gt 경우, stack), 팝, 2 = 2 피연산자로 합칩니다 함께 맨 위 사업자 스태킹하고 누름식 백됩니다 , 연산자에서 피연산자 진단트리는 않는 한 이 구조
  • 현재 스택 위에 있는 한 다음 연산자입니다 높은 순위에 있다.

이로 인해 미국 문제를 취급료 브래킷에. 1 부는 (생각해봤죠) 솔루션을 우선 순위에 따라 각 연산자입니다 저장입니다 여러 변수에. 그래서 처음에는

  • int 더하기, 빼기 = 1;
  • div, int mul) = 2.

이제 볼 때마다 왼쪽 오른쪽 브래킷에서 볼 때마다 이 모든 변수에 의해 증분우선순위수준우선 브래킷에서 2gb/s, 감소, 모든 변수에 의해 2.

이렇게 하면 +) 에 비해 높은 순위에 3 (4+5) 는 * 및 3*4 스택할 드래그합니다 푸시할 않습니다. 대신 기다리는 5, 누름식 4+5 관심용 누름식 3\ (4+5).

&gt. 야, 그러나 내가 won& # 39, t give away &gt. 部门从 나쁜거라 솔루션을 사용하는 표준 &gt. 스위치 또는 경우 스테망 (스피커에만 &gt. 그런 좋은 ifs 계층화할). A &gt. 조금 더 나은 솔루션이 部门从 &gt. 함수 포인터를 사용하여 테이블을 &gt. 그리고 아마도 최선의 해결책이 &gt. 다형성 사용해야 합니다.

지난 20 년간 발전 통역사 다른 길로 가는 것으로 볼 수 있다 - 다형성 (예를 들어, 소박한 스몰토크 메타치르쿠라르 통역사) 함수에 대한 포인터 (소박한 스레드한 구축, 리스프 (lisp 코드를 c++컴파일러는) 전환하십시오 (소박한 바이트 코드 통역사), 그리고 이후 할 수 있는 매우 큰 인컨텍스트 jit 및 드릴링됩니다 - 클래스, 또는 (개를 다형 언어), 다형성 맞추기바인딩 유형 사례 디스패치하지 연산뿐 줄어들고 있으며, # 39, re you& 뒤로를 dell. 1 단계. # 39, & # 39 best& 어떤 정의. 사용 중인 여기서요?

예를 들어 있는 물건을 다형 솔루션은 확인 - here& # 39 의 한 내가 이전에, 그렇지만, 어느 스태킹하고 바이트코드 컴파일러 / 스위치이거나 runtime& # 39 의 경우 보통 you& # 39 더 활용, re, 몇 천 플로팅하는 말하도다 갖는 함수는 데이터 포인트.

Ll 파서 부여하느뇨 너회가 표현식에서는 진단트리 구체화하십시오 토크니저 (1) + 이 방법을 사용하면, 추상 클래스 &quot 평가하십시오 산술 mediaagent 지정값이 다형성 (a, b) &quot. 함수, 즉 무시됨 관련된 각 운영자가 (더하기, 빼기, 곱하기 등) 에 해당하는 값을 반환할 수 있는 정수 및 산술 연산자 및 나무를요 map_layer 평가하실 게시물로의 (?) 의 진단트리 주문 의해 횡단

문제는 아닌 것 같아요 파서 작성하는 방법에 대한 평가. 또는 오히려 작성하는방법에 표현식에서는 트리입니다 문자열으로.

39, 기본 클래스의 경우 반환하는 제표를 don& 정확히요 수 없다.

기본 구조를 &quot polymorphic"; 솔루션 (원하는거요 또 다른 방법은 것, 내가 don& # 39, t care 너희는너희가 구축하십시오 이와 함께, 또 가능한 코드 양이 함께 하고 싶어서 늘입니다) 은 스트림 객체를 데즈리얼리징 계층 (dynamic) 에서 사용한 일련의 알려진 형식.

이 솔루션은 남십자자리 다형성) 의 구현을 통해 정규 표현식을 객체에는 반복 패턴을 가지고 만들 수 있는 방법이 가능성이 높다. I. e. 매핑하십시오 충족되었으며 객체에는 BNF 또는 이와 유사한 구문을 팩터리의.

Re: 저스틴

진단트리에서 모습이 될 것이라고 생각한다.

  +
 / \
2  ( )
    |
    2

39 you& 기본적으로 가지고 &quot eval";; d 그냥, 그 아래에 있는 노드입니다 나무를요 평가합니다. 그럼 그냥 최적화되었는지 아웃하려면 것이라고 할 수 있다.

  +
 / \
2   2

이 경우 괄호 aren& 필요하며, t, t # 39 don& # 39 추가 없다. 그들은 아무 것도 추가 논리적으로 도왔으매 they& don& # 39, t, d # 39 그냥 그냥가요

자, 여기 내 소박한 구축상의. 미안, 내가 한 것은 쉽게 사용할 수 있는 변환하십시오 객체에는 느끼지 못했다. 같은 기분이 좀 이글거리 윌리 (# 39 에서 Steve&; s story).

#!/usr/bin/env python

#tree structure [left argument, operator, right argument, priority level]
tree_root = [None, None, None, None]
#count of parethesis nesting
parenthesis_level = 0
#current node with empty right argument
current_node = tree_root

#indices in tree_root nodes Left, Operator, Right, PRiority
L, O, R, PR = 0, 1, 2, 3

#functions that realise operators
def sum(a, b):
    return a + b

def diff(a, b):
    return a - b

def mul(a, b):
    return a * b

def div(a, b):
    return a / b

#tree evaluator
def process_node(n):
    try:
        len(n)
    except TypeError:
        return n
    left = process_node(n[L])
    right = process_node(n[R])
    return n[O](left, right)

#mapping operators to relevant functions
o2f = {'+': sum, '-': diff, '*': mul, '/': div, '(': None, ')': None}

#converts token to a node in tree
def convert_token(t):
    global current_node, tree_root, parenthesis_level
    if t == '(':
        parenthesis_level += 2
        return
    if t == ')':
        parenthesis_level -= 2
        return
    try: #assumption that we have just an integer
        l = int(t)
    except (ValueError, TypeError):
        pass #if not, no problem
    else:
        if tree_root[L] is None: #if it is first number, put it on the left of root node
            tree_root[L] = l
        else: #put on the right of current_node
            current_node[R] = l
        return

    priority = (1 if t in '+-' else 2) + parenthesis_level

    #if tree_root does not have operator put it there
    if tree_root[O] is None and t in o2f:
            tree_root[O] = o2f[t]
            tree_root[PR] = priority
            return

    #if new node has less or equals priority, put it on the top of tree
    if tree_root[PR] >= priority:
        temp = [tree_root, o2f[t], None, priority]
        tree_root = current_node = temp
        return

    #starting from root search for a place with higher priority in hierarchy
    current_node = tree_root
    while type(current_node[R]) != type(1) and priority > current_node[R][PR]:
        current_node = current_node[R]
    #insert new node
    temp = [current_node[R], o2f[t], None, priority]
    current_node[R] = temp
    current_node = temp

def parse(e):
    token = ''
    for c in e:
        if c <= '9' and c >='0':
            token += c
            continue
        if c == ' ':
            if token != '':
                convert_token(token)
                token = ''
            continue
        if c in o2f:
            if token != '':
                convert_token(token)
            convert_token(c)
            token = ''
            continue
        print "Unrecognized character:", c
    if token != '':
        convert_token(token)

def main():
    parse('(((3 * 4) / (1 + 2)) + 5)')
    print tree_root
    print process_node(tree_root)

if __name__ == '__main__':
    main()

39 이 c # 의 흡착, ve 사람이었는가부텀 i& 콘솔 앱을 함께 약간의 개념 증명. 가질 수도 있다는 느낌이 많이 나아 (해당 스위치를 문을 그레트노데 는 같은 어설픈 (it& # 39 의 좁히어 사촌 내가 연산자에서 클래스 이름을 매핑하려면 공백일) 가 있다). 모든 대한 제안 개선 방안은 매우 환영합니다.

using System;

class Program
{
    static void Main(string[] args)
    {
        string expression = "(((3.5 * 4.5) / (1 + 2)) + 5)";
        Console.WriteLine(string.Format("{0} = {1}", expression, new Expression.ExpressionTree(expression).Value));
        Console.WriteLine("\nShow's over folks, press a key to exit");
        Console.ReadKey(false);
    }
}

namespace Expression
{
    // -------------------------------------------------------

    abstract class NodeBase
    {
        public abstract double Value { get; }
    }

    // -------------------------------------------------------

    class ValueNode : NodeBase
    {
        public ValueNode(double value)
        {
            _double = value;
        }

        private double _double;
        public override double Value
        {
            get
            {
                return _double;
            }
        }
    }

    // -------------------------------------------------------

    abstract class ExpressionNodeBase : NodeBase
    {
        protected NodeBase GetNode(string expression)
        {
            // Remove parenthesis
            expression = RemoveParenthesis(expression);

            // Is expression just a number?
            double value = 0;
            if (double.TryParse(expression, out value))
            {
                return new ValueNode(value);
            }
            else
            {
                int pos = ParseExpression(expression);
                if (pos > 0)
                {
                    string leftExpression = expression.Substring(0, pos - 1).Trim();
                    string rightExpression = expression.Substring(pos).Trim();

                    switch (expression.Substring(pos - 1, 1))
                    {
                        case "+":
                            return new Add(leftExpression, rightExpression);
                        case "-":
                            return new Subtract(leftExpression, rightExpression);
                        case "*":
                            return new Multiply(leftExpression, rightExpression);
                        case "/":
                            return new Divide(leftExpression, rightExpression);
                        default:
                            throw new Exception("Unknown operator");
                    }
                }
                else
                {
                    throw new Exception("Unable to parse expression");
                }
            }
        }

        private string RemoveParenthesis(string expression)
        {
            if (expression.Contains("("))
            {
                expression = expression.Trim();

                int level = 0;
                int pos = 0;

                foreach (char token in expression.ToCharArray())
                {
                    pos++;
                    switch (token)
                    {
                        case '(':
                            level++;
                            break;
                        case ')':
                            level--;
                            break;
                    }

                    if (level == 0)
                    {
                        break;
                    }
                }

                if (level == 0 && pos == expression.Length)
                {
                    expression = expression.Substring(1, expression.Length - 2);
                    expression = RemoveParenthesis(expression);
                }
            }
            return expression;
        }

        private int ParseExpression(string expression)
        {
            int winningLevel = 0;
            byte winningTokenWeight = 0;
            int winningPos = 0;

            int level = 0;
            int pos = 0;

            foreach (char token in expression.ToCharArray())
            {
                pos++;

                switch (token)
                {
                    case '(':
                        level++;
                        break;
                    case ')':
                        level--;
                        break;
                }

                if (level <= winningLevel)
                {
                    if (OperatorWeight(token) > winningTokenWeight)
                    {
                        winningLevel = level;
                        winningTokenWeight = OperatorWeight(token);
                        winningPos = pos;
                    }
                }
            }
            return winningPos;
        }

        private byte OperatorWeight(char value)
        {
            switch (value)
            {
                case '+':
                case '-':
                    return 3;
                case '*':
                    return 2;
                case '/':
                    return 1;
                default:
                    return 0;
            }
        }
    }

    // -------------------------------------------------------

    class ExpressionTree : ExpressionNodeBase
    {
        protected NodeBase _rootNode;

        public ExpressionTree(string expression)
        {
            _rootNode = GetNode(expression);
        }

        public override double Value
        {
            get
            {
                return _rootNode.Value;
            }
        }
    }

    // -------------------------------------------------------

    abstract class OperatorNodeBase : ExpressionNodeBase
    {
        protected NodeBase _leftNode;
        protected NodeBase _rightNode;

        public OperatorNodeBase(string leftExpression, string rightExpression)
        {
            _leftNode = GetNode(leftExpression);
            _rightNode = GetNode(rightExpression);

        }
    }

    // -------------------------------------------------------

    class Add : OperatorNodeBase
    {
        public Add(string leftExpression, string rightExpression)
            : base(leftExpression, rightExpression)
        {
        }

        public override double Value
        {
            get
            {
                return _leftNode.Value + _rightNode.Value;
            }
        }
    }

    // -------------------------------------------------------

    class Subtract : OperatorNodeBase
    {
        public Subtract(string leftExpression, string rightExpression)
            : base(leftExpression, rightExpression)
        {
        }

        public override double Value
        {
            get
            {
                return _leftNode.Value - _rightNode.Value;
            }
        }
    }

    // -------------------------------------------------------

    class Divide : OperatorNodeBase
    {
        public Divide(string leftExpression, string rightExpression)
            : base(leftExpression, rightExpression)
        {
        }

        public override double Value
        {
            get
            {
                return _leftNode.Value / _rightNode.Value;
            }
        }
    }

    // -------------------------------------------------------

    class Multiply : OperatorNodeBase
    {
        public Multiply(string leftExpression, string rightExpression)
            : base(leftExpression, rightExpression)
        {
        }

        public override double Value
        {
            get
            {
                return _leftNode.Value * _rightNode.Value;
            }
        }
    }
}

Merritt
그는 10년 전 댓글을 달았습니다
0

하지만 나는 왜 좀 더 잘 볼 수 있는 통합, 전체 구축현 구문 분석 로직 트리가 표현식에서는 커플링 (coupling) 의 논리를 만들어 꼭 함께 진단트리 표현식에서는 구문 분석

또한 맵을 생성할 수 있습니다 (에 의해 제어됨을 xml 데이터베이스 문제지고 [코드 사전, 또는 각 클래스는 사용자 정의 적용되는 속성을 나타내는 노드) 및 그 사이에 너회의 토큰 클래스에 매핑됩니까. 여기서 문제가 반사 (또는 다른 기법을 통해 Activator) 을 사용하는 것은 해당 클래스를 생성할 수 있습니다.

Wilfred Knievel
그는 10년 전 댓글을 달았습니다
0

음 좋은 점, 다른 @merritt 다음에 있을 수 있습니다 (i have a free lunch 크랙 지금 이 시간. [제안 주셔서 감사합니다.

39 와 같은 몇 가지 기본적인 기법 등, ve 기록되었으므로 i& 파서

[접요사 - &gt. RPN] (http://en.wikipedia.org/wiki/Reverse_Polish_notation) 및 [그것을 야드] (http://en.wikipedia.org/wiki/Shunting_yard_algorithm) 및 [트리 순회] (http://en.wikipedia.org/wiki/Tree_traversal). [# 39 이것은 구축상의 I&, ve 지었지] (http://perlhobby.googlecode.com/svn/trunk/parser_v0.1/).

39 의 c++로 컴파일된 it& 모두에서 및 Linux, Windows.

/ 질문은 어떤 제안을 환영했다.

&gt. 따라서 모든 문제를 해결을 위해 시도하시겠습니까 let& # 39 의 세 가지 방법. How do you go 에서 산술 표현식에서는 &quot, 2 등 (예를 들어 있는 문자열) + (2) &quot. # 39 의, 함수 포인터를 사용하는 트리별 충족되었으며 표현식에서는 cascaded-if& 테이블 및 / 또는 다형성?

하지만 난 이 흥미로운 것은 이 속한 don& # 39 더 많은 것 같아요, t the realm of 객체중심형 프로그레밍스리 함께 할 것 [구문 분석 기법을] (ftp://ftp.cs.vu.nl/pub/dick/PTAPG_1st_Edition/BookBody.pdf).

앞서 언급한 대로 명이 사용하는 경우, 괄호 진단트리 표현식에서는 필요하지 않습니다. 이 때, re 연산 순서를 보면 사소한 및 명백하네 you& # 39 표현식에서는 진단트리 이 파서를 괄호 설정에 있다.

반면, 나머지 절반은 문제에 대한 답이 수락됨 실제로 구문 분석 솔루션 절반으로 표현식에서는 - - 여전히 미해결 사건이다. 일반적으로 이러한 신규인지 통해 문제를 해결할 수 있다 되부름 하향 구문 분석. 구문 분석 등 주로 쓰는 재미 운동, 기울이나 현대 툴과도 어학 구문 분석 가 있는 추상적인 빼냅니다 당신꺼에요.

    • 파서를 역시 더 큰 실수 허용하시겠습니까 경우 해당 구체화하십시오. 난 이미 DFA 만들 수 있는 C - 그것은 매우 애씀 동의하려면 부동 소수점 숫자 및 자세한 작업. 이때 유효함 떠 있는 지점은 다음과 같습니다. ,,, 10, 10 10.123 9.876e-5 1.0f .025 상술합니다. 이를 통해 내가 solaris. 일부 분배 (찬성하는 심플리스티 및 간략하게) 요청되었습니다 인터뷰에서.

@Justin:

Look at my 나타내는 대한 참고 노드입니다. 그 후 사용하는 경우 구성표가

2 + (2)

로 나타낼 수 있다

           .
          / \
         2  ( )
             |
             2

&gt. 혹시 이건 진짜 질문: &gt. 영국 서머 타임 (2) 로 나타낼 수 있는 방법은? &gt. 즉 부품입니다 날 때 깔아놓은 카펫에 걸려 넘어져 엉덩이에 &gt. up.

반복.

imo 기능 언어를 사용해야 합니다. 더 열심히 진단트리를 OO 에서 조작하는 표현하고 있다 "고 규정했다.

Brian Leahy
Dmitry Ponyatov
그는 3년 전 댓글을 달았습니다
0

정말? # 39 의 소박한 c++컴파일러는 that& 구축상의: 클래스 AST {vector&lt AST&g ;; 자식. void 누름식 (AST ); / 하위 추가, 들소, AST / yacc 는 eval () 에서 호출해야 파서 / / 반복 계산 자식 노드 (int = 0), 구체화하십시오 덤프하지 / / 덤프하지 함께 양식을 진단트리에서 탭들 */};

Dmitry Ponyatov
그는 3년 전 댓글을 달았습니다
0

Eval () 에서 오른쪽 확장하지만 본문: 위안 수 있겠어요 ddo 소박한 중첩할 같은 평가 = [0] - [0] / 라차일드 / 중첩할 &gt it& # 39 의 메모리 누수, eval () 의 아주 쉽게 attaboy 중첩할 [0] # 39 의 전에 객체에는 it& 평가. # 39 don& 내가 모르는 사이에 정말 쉽게 추적할 수 있는 경우, 어떻게 할 수 있지만, 몇 표현식에서는 com/go/4e6b330a_kr 공유됨 리프 숫자임 그냥 삭제했습니다.

Dmitry Ponyatov
그는 3년 전 댓글을 달았습니다
0

I forgot "구체화하십시오 발 '으로 라벨 () 은 스스로를 노드입니다 ast