comparison libinterp/parse-tree/lex.ll @ 20624:7c0e10f035bd

Extend parser to accept binary constants that begin with '0b' or '0B'. * NEWS: Announce change: * lex.ll: Define NUMBIN to be 0[bB] followed by 0,1, or '_'. Define NUMBER to be NUMREAL|NUMHEX|NUMBIN. *lex.ll (looks_like_bin): New function to detect 0[bB] prefix. *lex.ll (handle_numbe): Call looks_like_bin() and if found then convert binary string to double. * parser.tst: Add tests for new behavior.
author Rik <rik@octave.org>
date Fri, 09 Oct 2015 18:52:58 -0700
parents e34692daf663
children
comparison
equal deleted inserted replaced
20623:e34692daf663 20624:7c0e10f035bd
62 62
63 %{ 63 %{
64 64
65 #include <cctype> 65 #include <cctype>
66 #include <cstring> 66 #include <cstring>
67 #include <stdint.h>
67 68
68 #include <iostream> 69 #include <iostream>
69 #include <set> 70 #include <set>
70 #include <sstream> 71 #include <sstream>
71 #include <string> 72 #include <string>
326 Im [iIjJ] 327 Im [iIjJ]
327 CCHAR [#%] 328 CCHAR [#%]
328 IDENT ([_$a-zA-Z][_$a-zA-Z0-9]*) 329 IDENT ([_$a-zA-Z][_$a-zA-Z0-9]*)
329 FQIDENT ({IDENT}(\.{IDENT})*) 330 FQIDENT ({IDENT}(\.{IDENT})*)
330 EXPON ([DdEe][+-]?{D}{D_}*) 331 EXPON ([DdEe][+-]?{D}{D_}*)
332 NUMBIN (0[bB][01_]+)
333 NUMHEX (0[xX][0-9a-fA-F][0-9a-fA-F_]*)
331 NUMREAL (({D}{D_}*\.?{D_}*{EXPON}?)|(\.{D}{D_}*{EXPON}?)) 334 NUMREAL (({D}{D_}*\.?{D_}*{EXPON}?)|(\.{D}{D_}*{EXPON}?))
332 NUMHEX (0[xX][0-9a-fA-F][0-9a-fA-F_]*) 335 NUMBER ({NUMREAL}|{NUMHEX}|{NUMBIN})
333 NUMBER ({NUMREAL}|{NUMHEX})
334 336
335 ANY_EXCEPT_NL [^\r\n] 337 ANY_EXCEPT_NL [^\r\n]
336 ANY_INCLUDING_NL (.|{NL}) 338 ANY_INCLUDING_NL (.|{NL})
337 339
338 %% 340 %%
2656 || (nesting_level.is_brace () 2658 || (nesting_level.is_brace ()
2657 && ! looking_at_object_index.front ())); 2659 && ! looking_at_object_index.front ()));
2658 } 2660 }
2659 2661
2660 static inline bool 2662 static inline bool
2663 looks_like_bin (const char *s, int len)
2664 {
2665 return (len > 2 && s[0] == '0' && (s[1] == 'b' || s[1] == 'B'));
2666 }
2667
2668 static inline bool
2661 looks_like_hex (const char *s, int len) 2669 looks_like_hex (const char *s, int len)
2662 { 2670 {
2663 return (len > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')); 2671 return (len > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'));
2664 } 2672 }
2665 2673
2687 unsigned long ival; 2695 unsigned long ival;
2688 2696
2689 nread = sscanf (tmptxt, "%lx", &ival); 2697 nread = sscanf (tmptxt, "%lx", &ival);
2690 2698
2691 value = static_cast<double> (ival); 2699 value = static_cast<double> (ival);
2700 }
2701 else if (looks_like_bin (tmptxt, strlen (tmptxt)))
2702 {
2703 uint64_t ivalue = 0;
2704
2705 for (int i = 0; i < strlen (tmptxt); i++)
2706 {
2707 ivalue <<= 1;
2708 ivalue += static_cast<uint64_t> (tmptxt[i] == '1');
2709 }
2710
2711 value = static_cast<double> (ivalue);
2712 nread = 1; // Just to pass the assert stmt below
2692 } 2713 }
2693 else 2714 else
2694 { 2715 {
2695 char *idx = strpbrk (tmptxt, "Dd"); 2716 char *idx = strpbrk (tmptxt, "Dd");
2696 2717