fixed parser bug by filtering out all comments

This commit is contained in:
Moritz Gmeiner 2024-08-25 03:07:18 +02:00
commit b4e25ee561
3 changed files with 23 additions and 14 deletions

View file

@ -40,6 +40,7 @@ let rec show_expr ?(indent = 0) expr =
ident_s ^ show_binary_op op ^ "\n" ^ show_indented left.expr ^ "\n" ^ show_indented right.expr ident_s ^ show_binary_op op ^ "\n" ^ show_indented left.expr ^ "\n" ^ show_indented right.expr
| UnaryExpr { op; expr } -> ident_s ^ show_unary_op op ^ "\n" ^ show_indented expr.expr | UnaryExpr { op; expr } -> ident_s ^ show_unary_op op ^ "\n" ^ show_indented expr.expr
let show_expr_node expr_node = show_expr expr_node.expr
let make_expr_node (pos : Error.code_pos) (expr : expr) = { expr; pos } let make_expr_node (pos : Error.code_pos) (expr : expr) = { expr; pos }
let make_string (pos : Error.code_pos) (s : string) = make_expr_node pos (Literal (String s)) let make_string (pos : Error.code_pos) (s : string) = make_expr_node pos (Literal (String s))
let make_number (pos : Error.code_pos) (x : float) = make_expr_node pos (Literal (Number x)) let make_number (pos : Error.code_pos) (x : float) = make_expr_node pos (Literal (Number x))

View file

@ -8,18 +8,10 @@ open Stmt
type parse_result = (stmt_node list, parser_error list) result type parse_result = (stmt_node list, parser_error list) result
type stmt_result = (stmt_node, parser_error) result type stmt_result = (stmt_node, parser_error) result
type expr_result = (expr_node, parser_error) result type expr_result = (expr_node, parser_error) result
type state = { tokens : token list; errors_rev : parser_error list } type state = { tokens : token list }
let is_at_end state = (List.hd !state.tokens).token_type == Eof let is_at_end state = (List.hd !state.tokens).token_type == Eof
let advance state = state := { tokens = List.tl !state.tokens }
let append_error msg pos state =
let e = ParserError.make pos msg in
{ state with errors_rev = e :: state.errors_rev }
let advance state = state := { !state with tokens = List.tl !state.tokens }
let peek state = List.hd !state.tokens
let peek_tt (state : state ref) : token_type = (peek state).token_type
let cur_pos state = (peek state).pos
let next state = let next state =
assert (not ((List.hd !state.tokens).token_type == Eof)); assert (not ((List.hd !state.tokens).token_type == Eof));
@ -27,6 +19,10 @@ let next state =
advance state; advance state;
token token
let peek state = List.hd !state.tokens
let peek_tt (state : state ref) : token_type = (peek state).token_type
let cur_pos state = (peek state).pos
let advance_if state tt = let advance_if state tt =
if peek_tt state == tt then ( if peek_tt state == tt then (
advance state; advance state;
@ -187,6 +183,7 @@ let statement (state : state ref) : stmt_result =
let stmt = make_print pos expr in let stmt = make_print pos expr in
Ok stmt Ok stmt
| tt -> | tt ->
advance state;
let msg = let msg =
Printf.sprintf "Statement stating with %s not yet implemented" (show_token_type tt) Printf.sprintf "Statement stating with %s not yet implemented" (show_token_type tt)
in in
@ -200,17 +197,25 @@ let rec synchronise (state : state ref) =
advance state; advance state;
synchronise state synchronise state
let rec parse (tokens : token list) : parse_result = let rec parse_impl (state : state ref) : parse_result =
let state = ref { tokens; errors_rev = [] } in
let result = statement state in let result = statement state in
match result with match result with
| Ok stmt when peek_tt state == Eof -> Ok [ stmt ] | Ok stmt when peek_tt state == Eof -> Ok [ stmt ]
| Ok stmt -> | Ok stmt ->
let* stmts = parse !state.tokens in print_endline (show_stmt stmt.stmt);
let* stmts = parse_impl state in
Ok (stmt :: stmts) Ok (stmt :: stmts)
| Error e -> ( | Error e -> (
synchronise state; synchronise state;
if peek_tt state == Eof then Error [ e ] if peek_tt state == Eof then Error [ e ]
else else
let tail_result = parse !state.tokens in let tail_result = parse_impl state in
match tail_result with Ok _ -> Error [ e ] | Error es -> Error (e :: es)) match tail_result with Ok _ -> Error [ e ] | Error es -> Error (e :: es))
let parse (tokens : token list) : parse_result =
(* filter out all the comment tokens *)
let tokens =
List.filter (fun tok -> match tok.token_type with Comment _ -> false | _ -> true) tokens
in
let state = ref { tokens } in
parse_impl state

View file

@ -1,6 +1,9 @@
type stmt = Expr of Expr.expr_node | Print of Expr.expr_node type stmt = Expr of Expr.expr_node | Print of Expr.expr_node
and stmt_node = { stmt : stmt; pos : Error.code_pos } and stmt_node = { stmt : stmt; pos : Error.code_pos }
let show_stmt stmt =
match stmt with Expr expr -> Expr.show_expr expr.expr | Print expr -> Expr.show_expr expr.expr
let make_expr_stmt (pos : Error.code_pos) (expr : Expr.expr_node) : stmt_node = let make_expr_stmt (pos : Error.code_pos) (expr : Expr.expr_node) : stmt_node =
let stmt = Expr expr in let stmt = Expr expr in
{ stmt; pos } { stmt; pos }