I was still unhappy with the remaining duplication

that and the double-matching with different kinds of regexps; it should be more
robust now.
This commit is contained in:
Louis Gesbert 2021-08-20 14:23:10 +02:00
parent e7ad186bd7
commit dc026d0a7f
4 changed files with 27 additions and 79 deletions

View File

@ -521,12 +521,24 @@ let rec lex_code (lexbuf : lexbuf) : token =
| MR_DAY ->
L.update_acc lexbuf;
DAY
| MX_MONEY_AMOUNT
| Plus digit, MS_DECIMAL_SEPARATOR, Star digit ->
| MR_MONEY_PREFIX, digit, Opt (Star (digit | MR_MONEY_DELIM), digit), Opt (MC_DECIMAL_SEPARATOR, Rep (digit, 0 .. 2)), MR_MONEY_SUFFIX ->
let s = Utf8.lexeme lexbuf in
let units = Buffer.create (String.length s) in
let cents = Buffer.create 2 in
let buf = ref units in
for i = 0 to String.length s - 1 do
match s.[i] with
| '0'..'9' as c -> Buffer.add_char !buf c
| MC_DECIMAL_SEPARATOR -> buf := cents
| _ -> ()
done;
L.update_acc lexbuf;
MONEY_AMOUNT (Runtime.integer_of_string (Buffer.contents units), Runtime.integer_of_string (Buffer.contents cents))
| Plus digit, MC_DECIMAL_SEPARATOR, Star digit ->
let rex =
Re.(compile @@ whole_string @@ seq [
group (rep1 digit);
str MS_DECIMAL_SEPARATOR;
char MC_DECIMAL_SEPARATOR;
group (rep digit)
]) in
let dec_parts = R.get_substring (R.exec ~rex (Utf8.lexeme lexbuf)) in

View File

@ -88,7 +88,10 @@
(* Specific delimiters *)
#define MR_MONEY_OP_SUFFIX '$'
#define MS_DECIMAL_SEPARATOR "."
#define MC_DECIMAL_SEPARATOR '.'
#define MR_MONEY_PREFIX '$', Star hspace
#define MR_MONEY_DELIM ','
#define MR_MONEY_SUFFIX ""
(* Builtins *)
@ -107,28 +110,3 @@
let s = Utf8.lexeme lexbuf in \
let i = String.index s '.' in \
AT_PAGE (int_of_string (String.trim (String.sub s i (String.length s - i))))
(* More complex cases *)
#define MX_MONEY_AMOUNT \
0x24, Star hspace, digit, Star (digit | ','), Opt (MS_DECIMAL_SEPARATOR, Rep (digit, 0 .. 2)) -> \
let extract_parts = \
Re.(compile @@ seq [ \
group (seq [ digit; opt (seq [ rep (alt [digit; char ',']); digit]) ]); \
opt (seq [ str MS_DECIMAL_SEPARATOR; group (repn digit 0 (Some 2))]) \
]) \
in \
let full_str = Utf8.lexeme lexbuf in \
let only_numbers_str = String.trim (String.sub full_str 1 (String.length full_str - 1)) in \
let parts = R.get_substring (R.exec ~rex:extract_parts only_numbers_str) in \
(* Integer literal*) \
let units = parts 1 in \
let remove_commas = R.regexp "," in \
let units = \
Runtime.integer_of_string (R.substitute ~rex:remove_commas ~subst:(fun _ -> "") units) \
in \
let cents = \
try Runtime.integer_of_string (parts 2) with Not_found -> Runtime.integer_of_int 0 \
in \
L.update_acc lexbuf; \
MONEY_AMOUNT (units, cents)

View File

@ -95,7 +95,10 @@
(* Specific delimiters *)
#define MR_MONEY_OP_SUFFIX 0x20AC (* The euro sign *)
#define MS_DECIMAL_SEPARATOR ","
#define MC_DECIMAL_SEPARATOR ','
#define MR_MONEY_PREFIX ""
#define MR_MONEY_DELIM ' '
#define MR_MONEY_SUFFIX Star hspace, 0x20AC
(* Builtins *)
@ -114,27 +117,3 @@
let s = Utf8.lexeme lexbuf in \
let i = String.index s '.' in \
AT_PAGE (int_of_string (String.trim (String.sub s i (String.length s - i))))
(* More complex cases *)
#define MX_MONEY_AMOUNT \
digit, Star (digit | hspace), Opt (MS_DECIMAL_SEPARATOR, Rep (digit, 0 .. 2)), Star hspace, 0x20AC -> \
let extract_parts = \
Re.(compile @@ seq [ \
group (seq [ digit; opt (seq [ rep (alt [digit; char ' ']); digit]) ]); \
opt (seq [ str MS_DECIMAL_SEPARATOR; group (repn digit 0 (Some 2))]) \
]) \
in \
let str = Utf8.lexeme lexbuf in \
let parts = R.get_substring (R.exec ~rex:extract_parts str) in \
(* Integer literal*) \
let units = parts 1 in \
let remove_spaces = R.regexp " " in \
let units = \
Runtime.integer_of_string (R.substitute ~rex:remove_spaces ~subst:(fun _ -> "") units) \
in \
let cents = \
try Runtime.integer_of_string (parts 2) with Not_found -> Runtime.integer_of_int 0 \
in \
L.update_acc lexbuf; \
MONEY_AMOUNT (units, cents)

View File

@ -93,7 +93,10 @@
(* Specific delimiters *)
#define MR_MONEY_OP_SUFFIX '$'
#define MS_DECIMAL_SEPARATOR "."
#define MC_DECIMAL_SEPARATOR '.'
#define MR_MONEY_PREFIX ""
#define MR_MONEY_DELIM ','
#define MR_MONEY_SUFFIX Star hspace, "PLN"
(* Builtins *)
@ -112,27 +115,3 @@
let s = Utf8.lexeme lexbuf in \
let i = String.index s '.' in \
AT_PAGE (int_of_string (String.trim (String.sub s i (String.length s - i))))
(* More complex cases *)
#define MX_MONEY_AMOUNT \
digit, Star (digit | ','), Opt (MS_DECIMAL_SEPARATOR, Rep (digit, 0 .. 2)), Star hspace, "PLN" -> \
let extract_parts = \
Re.(compile @@ seq [ \
group (seq [ digit; opt (seq [ rep (alt [digit; char ',']); digit]) ]); \
opt (seq [ str MS_DECIMAL_SEPARATOR; group (repn digit 0 (Some 2))]) \
]) \
in \
let str = Utf8.lexeme lexbuf in \
let parts = R.get_substring (R.exec ~rex:extract_parts str) in \
(* Integer literal*) \
let units = parts 1 in \
let remove_commas = R.regexp "," in \
let units = \
Runtime.integer_of_string (R.substitute ~rex:remove_commas ~subst:(fun _ -> "") units) \
in \
let cents = \
try Runtime.integer_of_string (parts 2) with Not_found -> Runtime.integer_of_int 0 \
in \
L.update_acc lexbuf; \
MONEY_AMOUNT (units, cents)