2012-04-23 1 views
0

내가 이런 내 .Y 문법의 일부가 있다고 가정하자 진술 목록 후자에 관해서는 insert_stmt ... 함수를 통해 저장하지만, 처음에는 스택 맨 위로 보냅니다.은 yacc (들소) AST 단순화

제 질문은 : $$ = $ 1을 어떻게 처리합니까? 내 말은 insert_stmt_list는 구조체에 모든 것을 넣고 그곳에 있다는 것을 알고 그 값을 인쇄 할 수 있지만 $$ = S1은 어디로 간다? 그것을 읽는 방법? :-)

고마워요!

답변

1

Re : 어떻게 읽습니까?

먼저 expr을 인식해야하는 왼쪽 재귀 문법이 있습니다. 이것은 stmt으로 감소되고 make_new_stmt_list에 의해 생성 된 의미 값은 stmt1의 의미 값이 $$ = $1;으로됩니다.

그냥 "오른쪽에서 첫 번째 기호의 의미 값을 가져 와서 (유일한 경우에만 발생합니다)"를 의미하고 왼쪽 의미 치로 전파하십시오. $1가 오른쪽에 stmt 으 여기

stmt : ... 
    | stmt expr { $$ = insert_stmt_list($1, $2); } 

는 상기에서 $$에 할당 된 의미 론적 값이다

다음 다른 expr 볼 경우

는 파싱 다른 생산 계속 이전 감소는 stmt을 산출했다.

exprstmt의 기능을하도록 시스템을 설계했습니다. 또한 exprinsert_stmt_list에 대한 인수로 적합한 값을 생성합니다. 표현식은 목록입니다.

그래서 : 귀하의 의견은 단지 하나의 표현 E가있는 경우

  1. , 다음 나온다 stmt 그냥 표현이다.

    insert_stmt_list(E1, E2) 
    
  2. 세 표현이있는 경우, 다음 전체 stmt이 호출의 결과입니다 : 당신이 두 식 E1과 E2가있는 경우

  3. 후 emeges stmt은의 결과입니다

    insert_stmt_list(insert_stmt_list(E1, E2), E3) 
    

등등. 이것이 의미가 있는지의 여부는이 "삽입"작업의 의미에 달려 있습니다.

+0

큰 질문은 진술을 기대하고 있었다면 표현 대신 어떻게 다루는 것이 었는가? 나는 일반적인 구조체를 사용하여 이것을 처리 할 수 ​​있었다. {is_STATEMENT, is_EXPRESSION, ...} 플래그와 각각의 구조체에 대한 포인터가있다. 이 모든 것은 C가 포인터의 유형을 알 수 없기 때문입니다. – Nitrate

+0

당신은 Lisp 추상 구문을 볼 수 있습니다. 평가의 기본 구문 단위는 표현식입니다. 단일 표현식이 예상되는 곳에 여러 표현식이 부작용으로 평가되기를 원하면'progn'과 같은 연산자를 사용할 수 있습니다 :'(progn expr1 expr2 ... exprn)'. 이것은 불필요한 노드가 아닙니다. – Kaz

0

그것은이 같은 것을 작성하는 더 관용적이다 :

stmt : expr { $$ = make_new_stmt_list($1); } 
     | stmt expr { $$ = insert_stmt_list($1, $2); } 

방법 중 하나 또는 다른, 당신이 문 목록 데이터 구조에 표현 된 데이터 구조를 포장해야합니다.

+1

솔루션의 문제점은 ast (추상 구문 트리) 용도로 무의미한 노드를 버릴 때 문 목록을 작성한다는 것입니다. 그래서 스택 $$ = $ 1의 최상위에 값을 넣는 것이 길 이었지만 모든 것이 흐려지는 결론에 도달했습니다 :-) – Nitrate

+0

표현식 목록과 단일 표현식의 구분은 꼭 필요한 것은 아닙니다. 이것이 추상 구문에서 발견되는 일종의 것입니다. 사실 당신이 그것을 추상화하지 못하게하는 방법; 귀하의 코드는 문법을 그대로 사용하고 있습니다. 나는. 'stmt : expr'은 구문 적으로 구문이 하나의 표현식이라고 주장합니다. 그래서 당신은 그것을 $$ = $ 1'으로 변환했습니다. 보다 추상적 인 관점은이 왼쪽 재귀 적 생산물이 단지 하나의 요소를 가질 수있는 시퀀스를 만드는 "지그"에 불과하다는 것입니다. – Kaz