Hi, I am writing my own parser for expressions and want to use cln for parsing integers within these expressions, specifically using read_integer (const cl_read_flags& flags, const char * string, const char * string_limit, const char * * end_of_parse) . Unfortunately this fails with a cln::read_number_bad_syntax_exception if the integer immediately precedes a "/" (example attached). I have traced the cause back to line 119 in cl_I_read.cc. My suspicion is that the check for "/" originates from the rational case (as the file states that the code is a condensed version of read_rational()) and could simply be removed, but I am not familiar enough with the code to be certain this would not break other use cases. Even though I can work around this by to determining the end of the integer before the call and setting string_limit accordingly, I would appreciate a fix for this issue. Cheers, Thomas Luthe
Hi, On 04/27/2017 02:56 PM, Thomas Luthe wrote:
I am writing my own parser for expressions and want to use cln for parsing integers within these expressions, specifically using
read_integer (const cl_read_flags& flags, const char * string, const char * string_limit, const char * * end_of_parse) .
Unfortunately this fails with a cln::read_number_bad_syntax_exception if the integer immediately precedes a "/" (example attached). I have traced the cause back to line 119 in cl_I_read.cc. My suspicion is that the check for "/" originates from the rational case (as the file states that the code is a condensed version of read_rational()) and could simply be removed, but I am not familiar enough with the code to be certain this would not break other use cases.
Even though I can work around this by to determining the end of the integer before the call and setting string_limit accordingly, I would appreciate a fix for this issue.
You're attempting to read string "1/2" into an cl_I, but you don't tell the read_integer function where the integer ends. In this case, the "the string in memory must contain exactly one number and nothing more, else an exception will be thrown" (quoted from section 5.2 of the manual). You really should do some basic string parsing before passing strings to the CLN input function. All my best, -richy. -- Richard B. Kreckel <https://in.terlu.de/~kreckel/>
Hi, thanks for your reply. The manual only states that the string must contain exactly one number if end_of_parse is null, which it is not in my example. In the non-null case read_integer itself checks the end of the integer input and stores the position of the character after the integer in *end_of_parse. This works as expected for any non-integer characters like +,*,-,... with / being the only exception. If I parse e.g. "1*2" I get a return value of 1 and *end_of_parse contains a pointer to the "*". I can of course as you say parse the string for the end of the integer in advance, but since read_integer already performs this task, it seems like an unnecessary overhead. Cheers, Thomas Luthe On 01/05/17 22:21, Richard B. Kreckel wrote:
Hi,
I am writing my own parser for expressions and want to use cln for parsing integers within these expressions, specifically using
read_integer (const cl_read_flags& flags, const char * string, const char * string_limit, const char * * end_of_parse) .
Unfortunately this fails with a cln::read_number_bad_syntax_exception if the integer immediately precedes a "/" (example attached). I have traced the cause back to line 119 in cl_I_read.cc. My suspicion is that the check for "/" originates from the rational case (as the file states that the code is a condensed version of read_rational()) and could simply be removed, but I am not familiar enough with the code to be certain this would not break other use cases.
Even though I can work around this by to determining the end of the integer before the call and setting string_limit accordingly, I would appreciate a fix for this issue. You're attempting to read string "1/2" into an cl_I, but you don't tell
On 04/27/2017 02:56 PM, Thomas Luthe wrote: the read_integer function where the integer ends. In this case, the "the string in memory must contain exactly one number and nothing more, else an exception will be thrown" (quoted from section 5.2 of the manual).
You really should do some basic string parsing before passing strings to the CLN input function.
All my best, -richy.
Thomas Luthe wrote:
The manual only states that the string must contain exactly one number if end_of_parse is null, which it is not in my example. In the non-null case read_integer itself checks the end of the integer input and stores the position of the character after the integer in *end_of_parse. This works as expected for any non-integer characters like +,*,-,... with / being the only exception.
What you say is clearly a desirable behaviour of the read_integer function. However, I don't know whether read_integer can easily be changed to operate this way: the rational number and complex number readers possibly depend on the present behaviour. Also, the comments in <cln/integer_io.h> say read_integer is "undocumented" and that it "does strictly the same as the general read_complex". So, the relation between read_integer and the other readers is not clear to me. Therefore I agree with Richy, better pre-parse the string yourself, and use read_integer only for the second, number-crunching, phase. Bruno
Hi, On 05/02/2017 12:32 AM, Bruno Haible wrote:
Thomas Luthe wrote:
The manual only states that the string must contain exactly one number if end_of_parse is null, which it is not in my example. In the non-null case read_integer itself checks the end of the integer input and stores the position of the character after the integer in *end_of_parse. This works as expected for any non-integer characters like +,*,-,... with / being the only exception.
What you say is clearly a desirable behaviour of the read_integer function. However, I don't know whether read_integer can easily be changed to operate this way: the rational number and complex number readers possibly depend on the present behaviour.
It would come at the cost of the extra overhead that Thomas was fearing that has to be done by the caller now. (BTW, this cost is small compared to the O(N*log(N)) conversion to base 2^intDsize that comes afterwards.)
Also, the comments in <cln/integer_io.h> say read_integer is "undocumented" and that it "does strictly the same as the general read_complex". So, the relation between read_integer and the other readers is not clear to me.
Well, that comment is obviously wrong since read_integer *is* documented. I think that we should remove the comment and make it clear in the manual that this is a deprecated low-level function (or similar wording). Cheers -richy. -- Richard B. Kreckel <https://in.terlu.de/~kreckel/>
participants (3)
-
Bruno Haible
-
Richard B. Kreckel
-
Thomas Luthe