I reformulate a question I asked previously. The purpose is to understand how precedence works in parsing.
I would like to parse a statement a(3).value = 100
. parser.mly
as follows stops after reading .
, and returns an error.
However, if I move the part dedicated to argument_list
(en-globed by begin
and end
) to the end of the file (thus it is after l_expression
), the parsing works well.
In the case where the statement is parsed, it is reduced to a let_statement
of data_manipulation_statement
; a(3).value
is reduced to member_access_expression
; a(3)
is reduced to a index_expression
; and 3
is reduced to argument_list
.
In the case where the statement cannot be parsed, it seems that it tries to reduce the beginning of the statement to a call_statement
of control_statement
... it ends by an error.
I always thought that, no matter what the precedence are, parsing always rejects the reductions which cannot end by succeeding. But there it seems that it tried and failed, and refused to try other possibilities...
Could anyone help to clarify?
statement:
| control_statement { $1 }
| data_manipulation_statement { BS_DMS $1 }
control_statement: | control_statement_except_multiline_if { BS_CSEMI $1 }
control_statement_except_multiline_if: | call_statement { $1 }
call_statement: | simple_name_expression argument_list { CSEMI_SNE_AL ($1, $2) }
data_manipulation_statement: | let_statement { $1 }
let_statement: | l_expression EQUAL expression { DMS_let (None, $1, $3) }
simple_name_expression: | name { $1 }
index_expression: | l_expression LPAREN argument_list RPAREN { IE_LE_AL ($1, $3) }
member_access_expression: | l_expression DOT unrestricted_name { MAE_LE_UN ($1, $3) }
literal_expression: | INTEGER { LIE_INT $1 }
unrestricted_name: | name { UN_N $1 }
name: | untyped_name { N_UN $1 }
untyped_name: | IDENTIFIER { UN_I $1 }
expression:
| l_expression { E_LE $1 }
| value_expression { E_VE $1 }
value_expression:
| literal_expression { VE_LIE $1 }
| parenthesized_expression { VE_PE $1 }
(***** begin argument_list *****)
argument_list: | positional_or_named_argument_list { AL_PONAL $1 }
positional_or_named_argument_list:
| positional_argument_COMMAs required_positional_argument { PONAL_PAs_RPA (List.rev $1, $2) }
positional_argument_COMMAs:
/* empty */ { [] }
| positional_argument_COMMAs positional_argument COMMA { $2 :: $1 }
positional_argument: | argument_expression { $1 }
required_positional_argument: | argument_expression { $1 }
argument_expression: | expression { AE_expression (None, $1) }
(***** end argument_list *****)
l_expression:
| simple_name_expression { LE_SNE $1 }
| index_expression { LE_IE $1 }
| member_access_expression { LE_MAE $1 }