2011-08-12 2 views
3

필자의 들소 문법에 문제가있다. 나는 한 쌍의 교대/감소를 가지고 있고, 6은 감소/감소한다. 문제는 파서가 이전에 토큰 중에서 선택할 것을 알아야하기 때문에 축소/축소 충돌이 어떻게 발생하는지 이해할 수 없다는 것입니다.들소 문법의 모호함

%token STRING_LITERAL 
%token INTEGER 
%token FLOAT 
%token CHARACTER 
%token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP 
%token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN 
%token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN 
%token XOR_ASSIGN OR_ASSIGN STATIC CATCH DOUBLE_COLON ELLIPSIS FUNCTION VAR 
%token SIZEOF 
%token GOTO 
%token AUTO 
%token THIS VAR_ASSIGN 
%token NAMESPACE 
%token TRY 
%token TYPE 
%token DECLTYPE 
%token PUBLIC 
%token PRIVATE 
%token PROTECTED 
%token USING 
%token THROW 
%token FRIEND 
%token COMPILETIME 
%token RUNTIME 
%token VIRTUAL 
%token ABSTRACT 
%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR CONTINUE BREAK RETURN 
%% 

global_scope_definition 
    : namespace_definition 
    | function_definition 
    | variable_definition 
    | using_definition 
    | type_definition; 

global_scope_definitions 
    : global_scope_definition 
    | global_scope_definitions global_scope_definition 

program 
    : global_scope_definitions; 

type_expression 
    : expression 

variable_assignment 
    : VAR_ASSIGN; 

name_or_qualified_name 
    : IDENTIFIER 
    | name_or_qualified_name '.' IDENTIFIER; 

namespace_definition 
    : NAMESPACE name_or_qualified_name '{' namespace_scope_definitions '}'; 

accessibility_definition 
    : PUBLIC ':' 
    | PRIVATE ':' 
    | PROTECTED ':' 
    | FRIEND ':'; 

using_definition 
    : USING IDENTIFIER '=' name_or_qualified_name ';' 
    | USING name_or_qualified_name ';'; 

type_definition 
    : TYPE IDENTIFIER type_literal; 

namespace_scope_definition 
    : accessibility_definition 
    | global_scope_definition; 

namespace_scope_definitions 
    : namespace_scope_definition 
    | namespace_scope_definitions namespace_scope_definition; 

accessibility_modifier 
    : PUBLIC 
    | PROTECTED 
    | PRIVATE 
    | FRIEND; 

accessibility_block 
    : phase_block 
    | accessibility_modifier phase_block; 

phase_modifier 
    : COMPILETIME 
    | RUNTIME; 

phase_block 
    : definition_block 
    | phase_modifier definition_block; 

definition_block 
    : default_definition_block 
    | STATIC static_definition_block 
    | VIRTUAL virtual_definition_block 
    | ABSTRACT abstract_definition_block; 

static_definition_block 
    : '{' static_definitions '}'; 

static_definitions 
    : static_definition 
    | static_definitions static_definition; 

static_definition 
    : variable_definition 
    | function_definition; 


abstract_definition_block 
    : '{' abstract_definitions '}'; 

abstract_definitions 
    : abstract_definition 
    | abstract_definitions abstract_definition; 

abstract_definition 
    : function_definition; 

virtual_definition_block 
    : '{' virtual_definitions '}'; 

virtual_definitions 
    : virtual_definition 
    | virtual_definitions virtual_definition; 

virtual_definition 
    : function_definition; 


default_definition_block 
    : '{' default_definitions '}'; 

default_definitions 
    : default_definition 
    | default_definitions default_definition; 

default_definition 
    : variable_definition 
    | function_definition 
    | constructor_definition 
    | destructor_definition 
    | type_definition; 

type_scope_definition 
    : using_definition 
    | default_definition 
    | accessibility_block; 

type_scope_definitions 
    : type_scope_definition 
    | type_scope_definitions type_scope_definition; 

destructor_definition 
    : '~' TYPE '(' ')' compound_statement; 

constructor_definition 
    : TYPE function_definition_arguments statements_and_inits; 

statements_and_inits 
    : inits compound_statement 
    | compound_statement; 

init 
    : ':' IDENTIFIER function_call_expression; 

inits 
    : init 
    | inits init; 

function_definition_arguments 
    : '(' ')' 
    | '(' function_argument_list ')'; 

function_definition 
    : type_expression IDENTIFIER function_definition_arguments compound_statement 
    | type_expression IDENTIFIER function_definition_arguments function_definition_arguments compound_statement; 

function_argument_definition 
    : IDENTIFIER 
    | type_expression IDENTIFIER 
    | IDENTIFIER variable_assignment expression 
    | type_expression IDENTIFIER variable_assignment expression 
    | IDENTIFIER variable_assignment '{' expressions '}' 
    | type_expression IDENTIFIER variable_assignment '{' expressions '}'; 

function_argument_list 
    : function_argument_definition 
    | function_argument_list ',' function_argument_definition; 

static_variable_definition 
    : STATIC variable_definition 
    | FRIEND variable_definition 
    | STATIC FRIEND variable_definition 
    | variable_definition; 

variable_definition 
    : IDENTIFIER variable_assignment expression ';' 
    | type_expression IDENTIFIER variable_assignment expression ';' 
    | type_expression IDENTIFIER ';' 
    | type_expression IDENTIFIER function_call_expression ';'; 

base_class_list 
    : ':' type_expression 
    | base_class_list ',' type_expression; 

type_literal 
    : base_class_list '{' type_scope_definitions '}' 
    | '{' type_scope_definitions '}' 
    | base_class_list '{' '}' 
    | '{' '}'; 

literal_expression 
    : INTEGER 
    | FLOAT 
    | CHARACTER 
    | STRING_LITERAL 
    | AUTO 
    | THIS 
    | TYPE type_literal; 

primary_expression  
    : literal_expression 
    | '(' expression ')' 
    | IDENTIFIER; 

expression 
    : variadic_expression; 

variadic_expression 
    : assignment_expression 
    | assignment_expression ELLIPSIS; 

assignment_operator 
    : '=' 
    | MUL_ASSIGN 
    | DIV_ASSIGN 
    | MOD_ASSIGN 
    | ADD_ASSIGN 
    | SUB_ASSIGN 
    | LEFT_ASSIGN 
    | RIGHT_ASSIGN 
    | AND_ASSIGN 
    | XOR_ASSIGN 
    | OR_ASSIGN; 

assignment_expression 
    : logical_or_expression 
    | unary_expression assignment_operator assignment_expression; 

logical_or_expression 
    : logical_and_expression 
    | logical_or_expression OR_OP logical_and_expression; 

logical_and_expression 
    : inclusive_or_expression 
    | logical_and_expression AND_OP inclusive_or_expression; 

inclusive_or_expression 
    : exclusive_or_expression 
    | inclusive_or_expression '|' exclusive_or_expression; 

exclusive_or_expression 
    : and_expression 
    | exclusive_or_expression '^' and_expression; 

and_expression 
    : equality_expression 
    | and_expression '&' equality_expression; 

equality_expression 
    : relational_expression 
    | equality_expression EQ_OP relational_expression 
    | equality_expression NE_OP relational_expression; 

comparison_operator 
    : '<' 
    | '>' 
    | LE_OP 
    | GE_OP; 

relational_expression 
    : shift_expression 
    | relational_expression comparison_operator shift_expression; 

shift_operator 
    : LEFT_OP 
    | RIGHT_OP; 

shift_expression 
    : additive_expression 
    | shift_expression shift_operator additive_expression; 

additive_operator 
    : '+' 
    | '-'; 

additive_expression 
    : multiplicative_expression 
    | additive_expression additive_operator multiplicative_expression; 

multiplicative_operator 
    : '*' 
    | '/' 
    | '%'; 

multiplicative_expression 
    : unary_expression 
    | multiplicative_expression multiplicative_operator unary_expression; 

lambda_expression 
    : '[' capture_list ']' function_argument_list compound_statement 
    | '[' capture_list ']' compound_statement; 
    | '[' ']' function_argument_list compound_statement 
    | '[' ']' compound_statement; 


default_capture 
    : '&' | '=' ; 

capture_list 
    : default_capture comma_capture_list 
    | comma_capture_list; 

comma_capture_list 
    : variable_capture 
    | comma_capture_list ',' variable_capture; 

variable_capture 
    : '&' IDENTIFIER 
    | '=' IDENTIFIER 
    | AND_OP IDENTIFIER; 

unary_operator 
    : '&' 
    | '*' 
    | '+' 
    | '-' 
    | '~' 
    | '!' 
    | INC_OP 
    | DEC_OP; 

unary_expression 
    : unary_operator unary_expression 
    | SIZEOF '(' expression ')' 
    | DECLTYPE '(' expression ')' 
    | lambda_expression 
    | postfix_expression; 

postfix_expression 
    : primary_expression { $$ = $1; } 
    | postfix_expression '[' expression ']' 
    | postfix_expression function_call_expression 
    | postfix_expression '.' IDENTIFIER 
    | postfix_expression PTR_OP IDENTIFIER 
    | postfix_expression INC_OP 
    | postfix_expression DEC_OP 
    | postfix_expression FRIEND; 

expressions 
    : expression 
    | expressions ',' expression; 

function_argument 
    : expression 
    | IDENTIFIER variable_assignment '{' expressions '}' 
    | IDENTIFIER variable_assignment expression; 

function_arguments 
    : function_argument 
    | function_arguments ',' function_argument; 

function_call_expression 
    : '(' function_arguments ')' 
    | '(' ')'; 

initializer_statement 
    : expression 
    | IDENTIFIER variable_assignment expression 
    | type_expression IDENTIFIER variable_assignment expression; 

destructor_statement 
    : expression '~' TYPE '(' ')' ';'; 

return_statement 
    : RETURN expression ';' 
    | RETURN ';'; 

try_statement 
    : TRY compound_statement catch_statements; 

catch_statement 
    : CATCH '(' type_expression IDENTIFIER ')' compound_statement; 

catch_statements 
    : catch_statement 
    | catch_statements catch_statement 
    | CATCH '(' ELLIPSIS ')' compound_statement 
    | catch_statements CATCH '(' ELLIPSIS ')' compound_statement; 

for_statement_initializer 
    : initializer_statement ';' 
    | ';'; 

for_statement_condition 
    : expression ';' 
    | ';'; 

for_statement_repeat 
    : expression 
    | ; 

for_statement 
    : FOR '(' for_statement_initializer for_statement_condition for_statement_repeat ')' statement; 

while_statement 
    : WHILE '(' initializer_statement ')' statement; 

do_while_statement 
    : DO statement WHILE '(' expression ')'; 

switch_statement 
    : SWITCH '(' initializer_statement ')' '{' case_statements '}'; 

default_statement 
    : DEFAULT ':' statements; 

case_statement 
    : CASE expression DOUBLE_COLON statements; 

case_statements 
    : case_statement 
    | case_statements case_statement { $1.push_back($2); $$ = std::move($1); } 
    | case_statements default_statement { $1.push_back($2); $$ = std::move($1); }; 

if_statement 
    : IF '(' initializer_statement ')' statement 
    | IF '(' initializer_statement ')' statement ELSE statement; 

continue_statement 
    : CONTINUE ';'; 

break_statement 
    : BREAK ';'; 

label_statement 
    : IDENTIFIER ':'; 

goto_statement 
    : GOTO IDENTIFIER ';'; 

throw_statement 
    : THROW ';' 
    | THROW expression ';'; 

runtime_statement 
    : RUNTIME compound_statement; 

compiletime_statement 
    : COMPILETIME compound_statement; 

statement 
    : compound_statement 
    | return_statement 
    | try_statement 
    | expression ';' 
    | static_variable_definition 
    | for_statement 
    | while_statement 
    | do_while_statement 
    | switch_statement 
    | if_statement 
    | continue_statement 
    | break_statement 
    | goto_statement 
    | label_statement 
    | using_definition 
    | throw_statement 
    | compiletime_statement 
    | runtime_statement 
    | destructor_statement ; 

statements 
    : statement 
    | statements statement; 

compound_statement 
    : '{' '}' 
    | '{' statements '}'; 

%% 

이것은 내 문법입니다. Bison은 function_argument_definitionprimary_expression 사이, 그리고 function_argument_definitionfunction_argument 사이의 모호한 것으로 문제를 제기합니다. 그러나, 나는 그것이 어떤 것을 만나게 될 때까지 어느 것을 골라야하는지 이미 알고 있어야한다는 것을 확신합니다. 이 모호성을 어떻게 해결할 수 있습니까?

답변

3

규칙이

function_definition: 
    type_expression IDENTIFIER function_definition_arguments compound_statement 

variable_definition: 
    type_expression IDENTIFIER function_call_expression ';' 

이 중 하나가 다양한 방법으로 같은 맥락에서 나타날 수있는 고려, 그래서 컴파일러는가에 ;에 도달 할 때까지보고있다 알 수있는 방법이 없습니다 variable_definition 또는 compound_statement{function_definition입니다. 결과적으로 처리가 function_definition_arguments 또는 function_call_expression인지 여부를 알 수 없으므로 축소/축소 충돌이 발생합니다.

이런 종류의 문제를 직접 찾으려면 -v 옵션으로 bison을 실행하여 작성한 상태 시스템을 보여주는 .output 파일을 생성해야합니다. 그런 다음 충돌이있는 주를보고 되돌아와 그 주에 어떻게 도달하는지 확인합니다. 귀하의 예에서 상태 280에는 감소/감소 충돌이 있습니다 (두 개). 거기에 도달하는 한 가지 방법은 병렬로 function_definition_argumentsfunction_call_expression을 파싱하는 상태 177입니다. 파서는 합법적 인 상태입니다. 상태 177은 상태 77에서 나옵니다. 상태 26은 위에서 재현 한 두 가지 규칙을 보여줍니다.

+0

젠장, 나는 그 모든 걸 잡았을 것이라 확신했다. 감사. – Puppy

관련 문제