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 }