I want to parse numbers such that:
-- zero is 0.0
-- numbers not equal zero are always signed with + or -
-- both parts before and after dot are obligatory
-- trailing or heading zeros are not allowed
Valid numbers: 0.0 +2.0 -0.2 +201.0 -0.0004 -1.05 +22.10001
Invalid numbers: +0.0 (signed zero, should be 0.0) +02.0 (heading zero, should be +2.0) -2.00100 (trailing zeros, should be -2.001)
My grammar is:
Numb ~ '0.0' | Numb_Signed
Numb_Signed ~ Numb_Sign Numb_Rest
Numb_Sign ~ '-' | '+'
Numb_Rest ~ Numb_Rest_Both | Numb_Rest_Left | Numb_Rest_Right
Numb_Rest_Both ~ Nonzero Digits_Or_Nothing '.' Digits_Or_Nothing Nonzero
Numb_Rest_Left ~ Nonzero Digits_Or_Nothing '.0'
Numb_Rest_Right ~ '0.' Digits_Or_Nothing Nonzero
Digits ~ Digit+
Digits_Or_Nothing ~ Digit*
Digit ~ [0-9]
Nonzero ~ [1-9]
Is there a more simple solution? Or this is optimal?
More questions:
(1) is there a possibility to restrict numbers to be maximu 15 characters long?
(2) is it possible to read all digits after dot, because when it parses string "+1.000" it prints that it stopped parsing before "00", and for users it would be better to show that whole number failed, that is "+1.000"; so is there something like in perl6 grammars "not before":
Numb_Signed ~ Numb_Sign Numb_Rest <HERE NOT BEFORE ANY DIGIT>
Error:
Error in SLIF parse: No lexeme found at line 1, column 9
* String before error: +1.0
* The error was at line 1, column 9, and at character 0x0030 '0', ...
* here: 00
Marpa::R2 exception at ./
lnaznum.pl line 68.