2011-08-12 72 views
3

我的野牛語法有問題。我有一對移動/減少,很好,六個減少/減少。問題是我不明白減少/減少衝突是如何發生的,因爲解析器應該知道先前從令牌中選擇哪一個。野牛語法中的歧義

%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 '}'; 

%% 

這是我的語法。野牛在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或中的{,function_definition。因此無法判斷其處理function_definition_arguments還是function_call_expression,從而導致您看到的減少/減少衝突。

要自己找到這類問題,您需要運行帶有-v選項的野牛來生成一個.output文件,以顯示它所構建的狀態機。然後你看看衝突狀態和回溯狀態,看看它是如何到達這些州的。在你的例子中,狀態280有(兩個)減少/減少衝突。到達那裏的一種方式是狀態177,它並行解析function_definition_argumentsfunction_call_expression - 解析器處於合法狀態。狀態177來自狀態77,來自狀態26,它顯示了我在上面重現的兩條規則。

+0

該死的,我確定我抓住了所有這些。謝謝。 – Puppy