1 module pegged.examples.numbers;
2 
3 import pegged.grammar;
4 
5 /// Numbers
6 mixin(grammar(`
7 Numbers:
8     Scientific <~ Floating ( ('e' / 'E' ) Integer )?
9     Floating   <~ Integer ('.' Unsigned )?
10     Unsigned   <~ [0-9]+
11     Integer    <~ Sign? Unsigned
12     Hexa       <~ [0-9a-fA-F]+
13     Sign       <- '-' / '+'
14 `));
15 
16 unittest
17 {
18     string[] testNumbers =
19     [
20         "0", "0.0", "0.01",
21         "-0", "+0", "-0.0", "+0.0",
22         "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
23         "0123456789",
24         "123", "123.0", "123.01", "-123", "-123.0", "-123.01",
25         "-123e+12", "-123e-12", "+123e+12", "+123e-12", "-123E+12", "-123E-12", "+123E+12", "+123E-12",
26         "123.456e+00", "123.456E+00", "123.456e-00", "123.456E-00",
27         "-123.456e+00", "-123.456E+00", "-123.456e-00", "-123.456E-00",
28         "+123.456e+00", "+123.456E+00", "+123.456e-00", "+123.456E-00"
29     ];
30 
31     foreach(i,number; testNumbers)
32     {
33         assert(Numbers(number).matches == [number]); // Shall parse
34     }
35 
36     // Failures
37     testNumbers =
38     [
39         ".", ".0", "0.", "123..456",
40         "", "abc", "+", "-", "+.", "-.",
41         "--1", "++1", "+-1", "-+1",
42         "1e", "1e+", "1e-","1ee"
43     ];
44 
45     foreach(i,number; testNumbers)
46     {
47         assert(Numbers(number).matches != [number]); // None shall parse
48     }
49 
50     // Hexadecimal numbers
51     testNumbers =
52     [
53         "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
54         "A", "B", "C", "D", "E", "F",
55         "a", "b", "c", "d", "e", "f",
56         "0123456789ABCDEF",
57         "0123456789abcdef",
58         "DEADBEEF", "0123BEEF", "DEAD0123",
59         "deadbeef", "0123beef", "dead0123",
60         "123E", "123e"
61     ];
62 
63     foreach(number; testNumbers)
64     {
65         assert(Numbers.decimateTree(Numbers.Hexa(number)).matches == [number]); // Shall parse
66     }
67 
68     // Hexadecimal failures
69     testNumbers =
70     [
71         "", "G", "g", "-1", "123.456", "123e+100"
72     ];
73 
74     foreach(number; testNumbers)
75     {
76         assert(Numbers.decimateTree(Numbers.Hexa(number)).matches != [number]); // None shall parse
77     }
78 }