5

계산기 언어 용 LL (1) 하향식 파서를 구현하려고했습니다. 그것은 단지 합계, 빼기, 나누기 및 곱하기 수 있습니다. 괄호가 없습니다. 이 문법은 LL (1) 파서에 적합하지 않습니다으로왼쪽 연관 연산자가 하향식 LL (1) 파서가 이해할 수있는 방식으로 표현 될 수 있습니까?

S -> A 

A -> B + A 
    | B - A 
    | B 

B -> int * B 
    | int/B 
    | int 

, 나는 그것을 아주 약간 수정했다 :

S -> A 

A -> B A' 
A'-> + A 
    | - A 
    | λ 

B -> int B' 
B'-> * B 
    |/B 
    | λ 

문제는 이제 문법이를 위해 왼쪽부터 결합되지 않는 것입니다 4 명의 연산자가 표시되어 있으므로 그렇게해야합니다. 이 문제를 해결하는 방법? 그렇게 할 수 있습니까?

+1

"LL (1) 파서를 사용하지 마십시오"라는 대답을 찾고 있지 않다고 가정합니다. 그러나 그것은 사실입니다 :'LL (1)'파서는 표현을 파싱하기에 적합하지 않습니다; 무엇인가의 이유로'LR (1)'을 사용하고 싶지 않다면, Pratt 파서 또는 연산자 우선 구문 분석기를 작성하십시오 ("Shunting Yard algorithm"참조). – rici

+1

글쎄, 나는 파서에 대해 배우는 중이다. 여러 종류의 파서에 대해 간단한 계산기 언어를 구현하려고했습니다. 당신은 LL (1)로 계산기를 수행 할 수 없다는 것을 말하고 있습니까? –

+0

나는 그것이 불가능하다는 것을 말하지 않고있다. 그것은 사소한 것이 아니라는 것이다. LL (1) 구문 분석기를 사용하여 수정 된 문법에 대한 구문 분석 트리를 생성 한 다음 구문 분석 트리에서 변환을 역변환하여 원본 문법에 대한 구문 분석 트리를 만들 수 있습니다. – rici

답변

6

재귀를 반복으로 바꾸면 왼쪽 연관성을 얻을 수 있습니다. 다음의 sort-of-pseudocode는 단순성을 위해 값을 직접 계산하지만 동일한 메소드를 사용하여 구문 분석 트리를 생성 할 수 있습니다.

function A() { 
    val = B(); 
    t = peek(); 
    while (t=='+' || t=='-') { 
    match(t); 
    val1 = B(); 
    if (t=='+') 
     val = val + val1; 
    else 
     val = val - val1; 
    t = peek(); 
    } 
    return(val) 
} 
peek() 그것을 먹는 않고 다음 토큰을 반환

match() 다음 토큰을 먹는다. B()에 대해서도 똑같은 일을 할 것입니다.