Skip to content

Commit 1df15b1

Browse files
authored
Merge pull request #1587 from stan-dev/improve-parser-error-fn-types
Make the syntax error when declaring a function with constrained arguments more specific
2 parents 9157643 + 954adae commit 1df15b1

40 files changed

Lines changed: 1081 additions & 431 deletions

src/frontend/Parse.ml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ let drive_parser parse_fun =
1111
(Preprocessor.current_buffer ())
1212
() in
1313
let success prog = {prog with Ast.comments= Preprocessor.get_comments ()} in
14-
let failure error_state =
14+
let failure prev error_state =
1515
(* see the Menhir manual for the description of error messages support *)
1616
let env =
1717
match error_state with
@@ -34,11 +34,19 @@ let drive_parser parse_fun =
3434
[%message
3535
"Failed to find error for parser error state " (state : int)] in
3636
let location =
37+
let env =
38+
match prev with
39+
(* if we errored because of one of our UNREACHABLE token, use the
40+
location immediately preceding for a more informative error *)
41+
| Interp.InputNeeded prev_env
42+
when Interp.acceptable prev Parser.UNREACHABLE Lexing.dummy_pos ->
43+
prev_env
44+
| _ -> env in
3745
Preprocessor.location_span_of_positions (Interp.positions env) in
3846
Syntax_error.parse_error message location in
3947
let startp = (Preprocessor.current_buffer ()).lex_curr_p in
4048
Syntax_error.try_with (fun () ->
41-
Interp.loop_handle success failure input (parse_fun startp))
49+
Interp.loop_handle_undo success failure input (parse_fun startp))
4250

4351
let to_lexbuf file_or_code =
4452
match file_or_code with

src/frontend/parser.messages

Lines changed: 487 additions & 348 deletions
Large diffs are not rendered by default.

src/frontend/parser.mly

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,33 @@ reserved_word:
267267
| UPPER { "upper", $loc, false }
268268
| ARRAY { "array", $loc, true }
269269

270+
(* useful for generating better messages in locations where these are not permitted *)
271+
%inline no_constraints:
272+
| basic_type LABRACK UNREACHABLE
273+
{ () }
274+
| constrained_vector UNREACHABLE
275+
{ () }
276+
| constrained_matrix UNREACHABLE
277+
{ () }
278+
279+
constrained_vector:
280+
| ORDERED
281+
| POSITIVEORDERED
282+
| SIMPLEX
283+
| UNITVECTOR
284+
| SUMTOZEROVEC
285+
{ () }
286+
287+
constrained_matrix:
288+
| CHOLESKYFACTORCORR
289+
| CHOLESKYFACTORCOV
290+
| CORRMATRIX
291+
| COVMATRIX
292+
| SUMTOZEROMAT
293+
| STOCHASTICCOLUMNMATRIX
294+
| STOCHASTICROWMATRIX
295+
{ () }
296+
270297
function_def:
271298
| rt=return_type name=decl_identifier LPAREN args=separated_list(COMMA, arg_decl)
272299
RPAREN b=statement
@@ -298,16 +325,11 @@ unsized_type:
298325
(* This is just a helper for the fact that we don't support the old array syntax any more
299326
It can go away at some point if it starts causing conflicts.
300327
*)
301-
| bt=basic_type dims=unsized_dims {
302-
parse_error
303-
(Fmt.str
304-
"%@{<light_red>Ill-formed type.%@} %@{<yellow>It looks like you are \
305-
trying to use the old array syntax.@ Please use the new syntax:%@}@ \
306-
@[<h>array[%s] %a@]@\n"
307-
(String.make (dims - 1) ',')
308-
UnsizedType.pp bt)
309-
$loc(dims)
310-
}
328+
| basic_type LBRACK UNREACHABLE
329+
{ (* This code will never be reached *)
330+
Common.ICE.internal_compiler_error
331+
[%message "the UNREACHABLE token should never be produced"]
332+
}
311333
| bt=basic_type
312334
{ grammar_logger "unsized_type";
313335
bt
@@ -339,6 +361,11 @@ basic_type:
339361
{ grammar_logger "basic_type COMPLEXROWVECTOR" ; UnsizedType.UComplexRowVector }
340362
| COMPLEXMATRIX
341363
{ grammar_logger "basic_type COMPLEXMATRIX" ; UnsizedType.UComplexMatrix }
364+
| no_constraints
365+
{ (* This code will never be reached. The parser state exists to make the error more specific. *)
366+
Common.ICE.internal_compiler_error
367+
[%message "the UNREACHABLE token should never be produced"]
368+
}
342369

343370
unsized_dims:
344371
| LBRACK cs=list(COMMA) RBRACK
@@ -386,13 +413,17 @@ decl(type_rule, rhs):
386413
let ty = (ty, trans) in
387414
parse_error
388415
(Fmt.str
389-
"%@{<light_red>Ill-formed declaration.%@} %@{<green>\";\"%@} expected \
390-
after variable declaration.@ %@{<yellow>It looks like you are trying \
416+
"@[<v 2>%@{<light_red>Ill-formed declaration.%@} %@{<green>\";\"%@} expected \
417+
after variable declaration.@ %@{<i>It looks like you are trying \
391418
to use the old array syntax.@ Please use the new syntax:%@}@ @[<h>%a \
392-
%s;@]@\n"
419+
%s;@]@]@\n"
393420
Pretty_printing.pp_transformed_type ty id.name)
394421
$loc(dims)
395422
}
423+
| DATABLOCK UNREACHABLE {
424+
Common.ICE.internal_compiler_error
425+
[%message "the UNREACHABLE token should never be produced"]
426+
}
396427
| ty=higher_type(type_rule)
397428
(* additional indirection only for better error messaging *)
398429
v = id_and_optional_assignment(rhs, decl_identifier) vs=option(remaining_declarations(rhs)) SEMICOLON
@@ -481,6 +512,11 @@ sized_basic_type:
481512
{ grammar_logger "COMPLEXROWVECTOR_var_type" ; (SizedType.SComplexRowVector e , Identity) }
482513
| COMPLEXMATRIX LBRACK e1=expression COMMA e2=expression RBRACK
483514
{ grammar_logger "COMPLEXMATRIX_var_type" ; (SizedType.SComplexMatrix (e1, e2), Transformation.Identity) }
515+
| no_constraints
516+
{ (* This code will never be reached. The parser state exists to make the error more specific. *)
517+
Common.ICE.internal_compiler_error
518+
[%message "the UNREACHABLE token should never be produced"]
519+
}
484520

485521
top_var_type:
486522
| INT r=range_constraint
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
transformed parameters {
2+
3+
}
4+
mdel {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
array[,,] x() {
2+
return ones_array(3, 3);
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
model {
2+
array[3,3] x;
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
model {
2+
array real x;
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
transformed parameters {
2+
jacobian += while;
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
transformed data {
2+
vector[2] foo = [ ;
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
model {
2+
real; foo;
3+
}

0 commit comments

Comments
 (0)