2017-11-03 38 views
0

저는 Decison 프로그래밍 언어의 (부분적인) 문법을 구현하기 위해 bison (3.0.4)과 lexer를 사용하고 있습니다. 나는 수업 내에있는 것만 구현하고 있습니다.Decaf 구문 분석 문제 (변수 선언 대 생성자)

내 작업은 간단합니다. 모든 생산 규칙 (문자열)을 트리에 저장 한 다음 인쇄하십시오. 예를 들어

, 당신은

class Foo { Foo(int arg1) { some2 a; } }하면 다음과 같은 출력

<ClassDecl>   --> class identifier <classBody> 
<ClassBody>   --> { <VariableDecl>* <ConstructorDecl>* <MethodDecl>* } 
<ConstructorDecl> --> identifier (<ParameterList>) <Block> 
<ParameterList>  --> <Parameter> <, Parameter>* 
<Parameter>   --> <Type> identifier 
<Type>    --> <SimpleType> 
<SimpleType>  --> int 
<Block>    --> { <LocalVariableDecl>* <Statement>* } 
<LocalVariableDecl> --> <Type> identifier ; 
<Type>    --> <SimpleType> 
<SimpleType>  --> identifier 

에게 첫 번째 문제를 (해결) 수 (해야)한다는

이었다 입력으로 다음 코드 줄이있는 경우 그것은 대신 생성자 선언을 구문 분석했지만 클래스 자체의 범위에는 변수 선언이 없습니다. (즉, 나는 단지 생성자의 블록 안에있다.) 이것은 해결되었습니다.

그럼에도 불구하고 다음과 같이 말하면 class abc { some1 abc; john doe; }syntax error, unexpected SEMICOLON, expecting LP이라고 말합니다. 그래서, 19 번 줄의 캐릭터가 문제를 일으 킵니다.

여기 .Y 파일 (만 classBody 규칙) 여기

class_decl: 
    CLASS ID LC class_body RC 
    ; 


/* FIXME: Gotta add more grammar here */ 
class_body: var_declmore constructor_declmore method_declmore 
    | var_declmore constructor_declmore 
    | var_declmore method_declmore 
    | constructor_declmore method_declmore 
    | method_declmore 
    | var_declmore 
    | constructor_declmore 
    | %empty 
    ; 


var_declmore: var_decl 
    | var_declmore var_decl 
    ; 


constructor_declmore: constructor_decl 
    | constructor_declmore constructor_decl 
    ; 

var_decl: type ID SEMICOLON 
    | type ID error 
    ; 

constructor_decl: ID LP parameter_list RP block 
    | ID error parameter_list RP block 
    ; 

전체 .Y 파일로 gist입니다.

+1

나는 그 파일에서 엄청난 경고를 받았다. 두 개의 시프트 감소 충돌 포함; 하나의 축소 감소 충돌; 그리고 쓸데없는 규칙에 대한 경고. 당신이 행동을 생략하면 BTW, 문법을 읽는 것이 훨씬 쉽습니다; [mcve]를 참조하십시오. – rici

+0

** expression **, ** name ** 및 ** new_expression **과 같은 규칙이 아직 사용되지 않았기 때문에 많은 경고가 표시됩니다. 그것들은 ** 규칙 **에서 사용됩니다.이 규칙은이 규칙 (** vardecl 및 생성자 충돌 **)에 대한 문제를 파악하기 위해 아직 구현되지 않았습니다. – oneturkmen

+0

해당 규칙만으로 [mcve]를 작성하면 훨씬 쉽게 찾을 수 있습니다. – rici

답변

2

중요한 문제는 constructor_declmore이 비어있을 수 있으며 var_declconstructor_decl이 모두 ID으로 시작될 수 있다는 것입니다.

파서가 constructor_decl을 인식하기 전에 문제가되는데, 이는 (빈) constructor_declmore을 줄여야하기 때문입니다. 그러나 분명히 var_declmore이 완료되었음을 알지 못하면 감소를 할 수 없습니다.

그래서 그것은 두 가지 조치 중 하나를 사이에 결정이있는 ID 볼 때 :

  1. 함으로써 더 이상 var_decl의가 없음을 결정, 빈 constructor_declmore 줄은; 또는

  2. var_decl의 구문 분석을 시작하려면 ID을 시프트하십시오.

bison/yacc는 항상 시프트 동작을 위해 시프트/감소 충돌을 해결합니다. 따라서이 경우 Foo은 으로 시작하는 ID이며 사용자가 유의하는 오류 메시지가 표시된다고 가정합니다.

문법에 의해 생성 된 축소/축소 충돌도 조사해야합니다. 이것은 method_declmore으로 시작하고 method_decl을 추가하여 method_declmore을 만드는 다른 가능한 방법과 충돌하는 method_declmore: method_decl 규칙에서 비롯됩니다.

+0

사실입니다. 그러나 ** classBody **에 대한 규칙을 변경함에 따라 이제 변수 선언을 제공하지만 ** constructor_decl ** 규칙을 일치 시키려고합니다. 편집을 확인하십시오. – oneturkmen

+0

@alwaysone : 답변을 마친 후에는 변경하지 마십시오. 새로운 질문이 있으면 따로 질문하십시오. – rici

+0

** classBody ** 정의로 내 문제가 해결되지 않아서 질문에 완전히 대답하지 못했습니다. ** classBody **의 적절한 선언과 동일한 문제가 계속 발생하기 때문에 크게 변경하지는 않습니다. – oneturkmen