YECC

2014-12-04 9 views
0

으로 (파이썬 등)을 들여 기반 구문을 구문 분석 나는 다음과 같은 코드 조각 한 :YECC

case 1 
of 2 
    3 
of 3 
    4 
5 

내 사용자 지정 토크 나이가 번역 것과 :하지만 나는

Tokens: [{'case',1}, 
     {integer,1,1}, 
     {eol,1}, 
     {'of',1}, 
     {integer,1,2}, 
     {block,[{integer,1,3}]}, 
     {eol,1}, 
     {'of',1}, 
     {integer,1,3}, 
     {block,[{integer,1,4}]}, 
     {eol,1}, 
     {integer,1,5}] 

을 아니에요

Nonterminals 
    grammar 
    statements statement 
    case_def case_conditions condition. 


Terminals 
    eol block 
    integer 
    case of. 


Rootsymbol grammar. 


grammar -> statements : '$1'. 


statements -> statement eol statements : ['$1'|'$3']. 
statements -> statement : ['$1']. 

statement -> case_def : '$1'. 
statement -> integer : '$1'. 


case_def -> 'case' integer case_conditions : ''. 

case_conditions -> case_condition case_conditions : ['$1'|'$2']. 
case_conditions -> case_condition : ['$1']. 

case_condition -> eol 'of' integer block : ''. 

그것은 나에게 다음과 같은 출력을 제공합니다 : 다음 Yecc으로 구문 분석 할 수있는

["syntax error before: ","5"] 

도움이 정말 감사합니다.

답변

1

비 터미널 목록에는 condition 대신 case_condition이 있어야한다고 생각합니다.

사용자 정의 스캐너가 들여 쓰기를 무시합니다. INDENTDEDENT에 대한 토큰을 방출해야합니다. 나는 example in yacc을 찾았다. 그런 다음 토큰을 사용하도록 문법을 변경할 수 있습니다.

이 예제에서는 시프트/감소 충돌이 발생합니다.

시프트/더 연산자 우선 순위 선언 가없는 경우 충돌이 변화에 찬성 해결 감소 : 문서는 것을 말한다.

  • case_condition 그래서 다음과 같을 수 있습니다

그것은 당신의 파서가 |

of 3 
    4| 
5 

로 표시 장소에 있고 새로운 라인을 볼 때,이 두 가지 옵션이 될 수 있음을 의미 구문 분석기는 "shift"를 계속해서 읽어야합니다.

  • 구문 분석기는 문장의 끝이 될 수 있으므로 구문 분석기는 이전에 모든 것을 문장으로 처리하고 넣어야합니다. 스택 또는 짧게 "축소"
  • 이러한 충돌 때문에 항상 시프트가 해결되므로 대소 문자를 시작한 후에 다음 문장을 넣을 수 없습니다! 문법을 바꿔야합니다. yecc:file/1까지 작업하면 경고가 생성되지 않습니다.

    힌트 :이 같은 들여 쓰기 모든 내부 케이스 :

    case 1 
        of 2 
         3 
        of 3 
         4 
    5 
    

    이 방법, 당신은 명확 case가 하나 개의 문장과 5 다른 것을 말하고있다. 파서에 대한 지식이 조금 녹슬었지만, 들여 쓰기 나 종결자를 추가하지 않으면 왼쪽에서 오른쪽 파서로 case_conditionstatement을 구별 할 수있는 문법을 작성할 수 없다고 생각합니다. .