POV-Ray : Newsgroups : povray.bugreports : Parse error: Uncategorized error thrown at parser/parsertypes.cpp line 62 Server Time
16 Apr 2024 17:53:22 EDT (-0400)
  Parse error: Uncategorized error thrown at parser/parsertypes.cpp line 62 (Message 4 to 13 of 13)  
<<< Previous 3 Messages Goto Initial 10 Messages
From: clipka
Subject: Re: Parse error: Uncategorized error thrown at parser/parsertypes.cppline 62
Date: 21 Mar 2019 15:18:32
Message: <5c93e388@news.povray.org>
Am 20.03.2019 um 19:27 schrieb William F Pokorny:

> I can confirm the v38 issue. Also running Ubuntu 18.04 though g++7 vs 
> Warren's 8.
> 
> It seems the v3.8 branch (commit 74b3ebe) needs a space ahead of the 
> macro #end statement to work as follows:
> 
> #macro LoadThing(filePath)
>      #include filePath
>   #end                 // <-- Add extra space before #end and OK
> 
> LoadThing("zoomBangCrash.inc")
> 
> and whenever the include file has an empty line, C++ comment style line, 
> C++ comment line and then a declare line. The following for 
> zoomBangCrash.inc, less the line numbers, is also a v3.8 parse issue if 
> there is no space ahead of the main file macro #end:
> 
> 01
> 02 //
> 03 //
> 04 #declare A=1;

Can't reproduce on Windows; neither with DOS line endings (CR+LF) nor 
with Unix line endings (LF).

I'm running a slightly modified version, but if any of those 
modifications make any difference, I wouldn't know which ones.

Do you have the time and energy to investigate this further?


Post a reply to this message

From: William F Pokorny
Subject: Re: Parse error: Uncategorized error thrown atparser/parsertypes.cppline 62
Date: 22 Mar 2019 06:44:33
Message: <5c94bc91$1@news.povray.org>
On 3/21/19 3:18 PM, clipka wrote:
> Am 20.03.2019 um 19:27 schrieb William F Pokorny:
> 
...
> 
> Can't reproduce on Windows; neither with DOS line endings (CR+LF) nor 
> with Unix line endings (LF).
> 
> I'm running a slightly modified version, but if any of those 
> modifications make any difference, I wouldn't know which ones.
> 
> Do you have the time and energy to investigate this further?

Not today with a family visit later, but I'll put it on the list to play 
with the issue more this weekend.

Bill P.


Post a reply to this message

From: William F Pokorny
Subject: Re: Parse error: Uncategorized error thrownatparser/parsertypes.cppline 62
Date: 24 Mar 2019 10:59:02
Message: <5c979b36$1@news.povray.org>
On 3/22/19 6:44 AM, William F Pokorny wrote:
> On 3/21/19 3:18 PM, clipka wrote:
>> Am 20.03.2019 um 19:27 schrieb William F Pokorny:
>>
> ...
>>
>> Can't reproduce on Windows; neither with DOS line endings (CR+LF) nor 
>> with Unix line endings (LF).
>>
>> I'm running a slightly modified version, but if any of those 
>> modifications make any difference, I wouldn't know which ones.
>>
>> Do you have the time and energy to investigate this further?
> 
> Not today with a family visit later, but I'll put it on the list to play 
> with the issue more this weekend.
> 
> 

That was painful to run down, but changing Parser::IsEndOfInvokedMacro() 
in the file source/parser/parser_tokenizer.cpp as in the attached file 
fixes the issue.

Have to admit I'm not sure even now I completely understand what was 
happening (how it could happen perhaps). We seem to have been comparing 
structures in the original - which I don't think c++ does by default?

return (Cond_Stack.back().PMac->endPosition ==
CurrentFilePosition()) && ...

If this true though, why no compile warning or error? In any case, once 
in a while on the structure compare some error got thrown and caught by 
the parser code and no message was set which is why we get the unhelpful 
generic something wrong message. Mostly calls to the compare above 
seemed to work - including ones prior to the failing one for the test 
case - returning false always.

I'm tempted to add a throw on a true test for the re-coded version then 
run a bunch of stuff to see if it true ever really happens. Have we been 
doing something like comparing pointers (and so false) always? But, I've 
already spent a day on this and I don't feel like spending additional 
time.

For the particular test cases you can also hard code that function to 
return false always and things work because that test is always false 
for it.

Lastly, I did try a debug -Og compile thinking maybe we had some 
compiler issue here, but it failed in the same way.

Anyone who better understands what happened / how direct struct compares 
could sort of seem to work, please feel free to jump in and explain.

Bill P.


Post a reply to this message


Attachments:
Download 'isendofinvokedmacro_update.txt' (1 KB)

From: clipka
Subject: Re: Parse error: Uncategorized errorthrownatparser/parsertypes.cppline 62
Date: 25 Mar 2019 18:55:29
Message: <5c995c61$1@news.povray.org>
Am 24.03.2019 um 15:59 schrieb William F Pokorny:

> That was painful to run down, but changing Parser::IsEndOfInvokedMacro() 
> in the file source/parser/parser_tokenizer.cpp as in the attached file 
> fixes the issue.

Well, that's a lead I might investigate. But as you don't seem to be 
confidently understanding what's going on, I'll be going with the 
presumption that this is not a proper fix but just a patch.

> Have to admit I'm not sure even now I completely understand what was 
> happening (how it could happen perhaps). We seem to have been comparing 
> structures in the original - which I don't think c++ does by default?
> 
> return (Cond_Stack.back().PMac->endPosition ==
> CurrentFilePosition()) && ...
> 
> If this true though, why no compile warning or error?

That's easily explained: The data is of type `LexemePosition`, which is 
a struct defining an overloaded comparison operator.

(In C++, structs and classes are the same category of beasts. The only 
semantic difference between `struct` and `class` is the default member 
and base class access: `struct` implies `public` by default, while 
`class` implies `private` by default. According to the language 
standard, it is even perfectly valid to pre-declare a type as `struct` 
and later define it as `class` or vice versa.)

The `LexemePosition` type holds a file offset, as well as a line and 
column number.

Comparison is done by file offset, but the code also features an 
assertion, which tests whether the comparison by line and column yields 
the same result. If the assertion fails, debug builds bomb (i.e. core 
dump or break into a debugger), and non-debug builds throw an exception 
to trigger a parse error.

(Usually such assertion tests are only enabled in debug builds, but in 
the parser they're currently deliberately enabled in all builds, because 
I don't fully trust my current understanding of the parser and the 
refactoring work I have based on that understanding.)

If `Cond_Stack.back().PMac->endPosition == CurrentFilePosition()` throws 
an exception, it means either of two things:

(A) The positions compared are from two different files, which means the 
calling code has failed to check whether it is even in the right file.

(B) The line/column tracking is buggy, and yields different positions in 
different situations.


> In any case, once 
> in a while on the structure compare some error got thrown and caught by 
> the parser code and no message was set which is why we get the unhelpful 
> generic something wrong message.

This is the default error message for failed assertions. Unfortunately 
somewhere along the chain of error message handling the location 
information for the assertion seems to be lost, the original exception 
should include the nformation that it was triggered in `parsertypes.h` 
line 62 (in my version of the file at any rate), maybe even that it was 
in function `LexemePosition::operator==` (depending on compiler). Maybe 
it's worth investigating and fixing that.


Post a reply to this message

From: clipka
Subject: Re: Parse error: Uncategorizederrorthrownatparser/parsertypes.cppline 62
Date: 25 Mar 2019 19:41:39
Message: <5c996733$1@news.povray.org>
Am 25.03.2019 um 23:55 schrieb clipka:

> If `Cond_Stack.back().PMac->endPosition == CurrentFilePosition()` throws 
> an exception, it means either of two things:
> 
> (A) The positions compared are from two different files, which means the 
> calling code has failed to check whether it is even in the right file.
> 
> (B) The line/column tracking is buggy, and yields different positions in 
> different situations.


Well, looking at the code of `IsEndOfInvokedMacro()` again, it 
_strongly_ reeks of scenario (A):

     return (Cond_Stack.back().PMac->endPosition ==
                 CurrentFilePosition()) &&
            (Cond_Stack.back().PMac->source.fileName ==
                 mTokenizer.GetInputStreamName());

should probably be swapped around, like so:

     return (Cond_Stack.back().PMac->source.fileName ==
                 mTokenizer.GetInputStreamName()) &&
            (Cond_Stack.back().PMac->endPosition ==
                 CurrentFilePosition());

so that the `LexemePosition` comparison operator is only invoked if the 
file names match.


I guess you got really lucky in your test (and the OP unlucky in their 
use case), in that you happen to have created the following scenario:

- A macro is invoked.
- That macro includes a different file.
- That included file happens to have a `#` (e.g. `#declare`) at the same 
file offset as the `#end` of the macro.
- However, the `#` happens to be in a different line and/or column.


In such a scenario, encountering the `#`, the parser would first test 
whether this is the `#end` of the macro it has been waiting for, calling 
`IsEndOfInvokedMacro()`.

`IsEndOfInvokedMacro()` in turn would checks whether the current file 
position matches that of the macro's `#end` by calling 
`LexemePostition::operator==`.

`LexemePostition::operator==` in turn would find that the file position 
does match. It would then verify that the match also reflects in line 
and column, and find that they differ, and report this inconsistency via 
an Exception.

`IsEndOfInvokedMacro()` wouldn't even get a chance to test whether it is 
looking at the right file, because its author (duh, I wonder who that 
stupid git might have been...) chose to do the two tests in the wrong order.


Now aside from the stupid git who authored `IsEndOfInvokedMacro()` 
there's someone else to blame for the situation, namely whoever thought 
it was a good idea to keep the stack of include files separate from the 
stack of pending "conditions". If they were using one and the same 
structure, having `INVOKING_MACRO_COND` on top of the stack would imply 
that we're in the file with the `#end`, and the file name test would be 
redundant.

I think it should be possible to merge the include stack into the 
"condition" stack without adverse effects, but I haven't finished work 
on that yet.


I should note that I haven't tested this hypothesis and fix for the 
error yet; I intend to do that as soon as I find the time, but of course 
you're welcome to beat me to it.


Post a reply to this message

From: William F Pokorny
Subject: Re: Parse error: Uncategorizederrorthrownatparser/parsertypes.cppline62
Date: 26 Mar 2019 06:46:20
Message: <5c9a02fc$1@news.povray.org>
On 3/25/19 7:41 PM, clipka wrote:
> Am 25.03.2019 um 23:55 schrieb clipka:
> 
>> If `Cond_Stack.back().PMac->endPosition == CurrentFilePosition()` 
>> throws an exception, it means either of two things:
>>
>> (A) The positions compared are from two different files, which means 
>> the calling code has failed to check whether it is even in the right 
>> file.
>>
>> (B) The line/column tracking is buggy, and yields different positions 
>> in different situations.
> 
> 
> Well, looking at the code of `IsEndOfInvokedMacro()` again, it 
> _strongly_ reeks of scenario (A):
> 
>      return (Cond_Stack.back().PMac->endPosition ==
>                  CurrentFilePosition()) &&
>             (Cond_Stack.back().PMac->source.fileName ==
>                  mTokenizer.GetInputStreamName());
> 
> should probably be swapped around, like so:
> 
>      return (Cond_Stack.back().PMac->source.fileName ==
>                  mTokenizer.GetInputStreamName()) &&
>             (Cond_Stack.back().PMac->endPosition ==
>                  CurrentFilePosition());
> 
> so that the `LexemePosition` comparison operator is only invoked if the 
> file names match.
> 
> 
> I guess you got really lucky in your test (and the OP unlucky in their 
> use case), in that you happen to have created the following scenario:
> 
> - A macro is invoked.
> - That macro includes a different file.
> - That included file happens to have a `#` (e.g. `#declare`) at the same 
> file offset as the `#end` of the macro.
> - However, the `#` happens to be in a different line and/or column.
> 
> 
> In such a scenario, encountering the `#`, the parser would first test 
> whether this is the `#end` of the macro it has been waiting for, calling 
> `IsEndOfInvokedMacro()`.
> 
> `IsEndOfInvokedMacro()` in turn would checks whether the current file 
> position matches that of the macro's `#end` by calling 
> `LexemePostition::operator==`.
> 
> `LexemePostition::operator==` in turn would find that the file position 
> does match. It would then verify that the match also reflects in line 
> and column, and find that they differ, and report this inconsistency via 
> an Exception.
> 
> `IsEndOfInvokedMacro()` wouldn't even get a chance to test whether it is 
> looking at the right file, because its author (duh, I wonder who that 
> stupid git might have been...) chose to do the two tests in the wrong 
> order.
> 
> 
> Now aside from the stupid git who authored `IsEndOfInvokedMacro()` 
> there's someone else to blame for the situation, namely whoever thought 
> it was a good idea to keep the stack of include files separate from the 
> stack of pending "conditions". If they were using one and the same 
> structure, having `INVOKING_MACRO_COND` on top of the stack would imply 
> that we're in the file with the `#end`, and the file name test would be 
> redundant.
> 
> I think it should be possible to merge the include stack into the 
> "condition" stack without adverse effects, but I haven't finished work 
> on that yet.
> 
> 
> I should note that I haven't tested this hypothesis and fix for the 
> error yet; I intend to do that as soon as I find the time, but of course 
> you're welcome to beat me to it.

Thanks for the detailed explanations and, though I'm busy with RL 
starting in a little while today, I think you've figured it out.

I know from looking at the values the position was matching and the line 
and column were not. Further, when I look at my test cases (all some 
pretty close variation of Warren's original) the failing ones all have 
the # of the declare in just the right spot as you suggested. I'd not 
recognized this was so.

My patch, then, just avoided the assertion in the 
LexemePosition::operator== I suppose. I also didn't know the parser 
assertions were today on always and I wasn't thinking an assert could 
cause the exception.

Quick additional question. Is it the --enable-debug configure flag that 
- normally - turns on the pov asserts? I've never verified this 
assumption of mine by creating a pov assert in the code I know should 
fail.

Bill P.


Post a reply to this message

From: clipka
Subject: Re: Parse error:Uncategorizederrorthrownatparser/parsertypes.cppline62
Date: 26 Mar 2019 08:10:24
Message: <5c9a16b0$1@news.povray.org>
Am 26.03.2019 um 11:46 schrieb William F Pokorny:

> Quick additional question. Is it the --enable-debug configure flag that 
> - normally - turns on the pov asserts? I've never verified this 
> assumption of mine by creating a pov assert in the code I know should fail.

To be honest, I haven't a clue. I'm not sure what the `--enable-debug` 
flag does exactly (it's some standard mechanism in the Automake tools), 
nor whether and how assertions are enabled or disabled in Unix builds.

I'm pretty sure that `--enable-debug` does enable the creation of debug 
information in the binaries, so that a debugging tool can correlate 
binary code addresses with original source code lines, so that you can 
e.g. set breakpoints and step through the code line by line with a 
debugger. I also wouldn't be surprised if it turns off optimizations by 
default, because those tend to re-order instructions and make a 
line-by-line correlation impossible. Whether it does anything beyond 
that I do not know. It might dictate whether `NDEBUG` is defined or not, 
which would conceivably disable/enable assertions.


Post a reply to this message

From: William F Pokorny
Subject: Re: Parseerror:Uncategorizederrorthrownatparser/parsertypes.cppline62
Date: 28 Mar 2019 06:49:32
Message: <5c9ca6bc$1@news.povray.org>
On 3/26/19 8:10 AM, clipka wrote:
> Am 26.03.2019 um 11:46 schrieb William F Pokorny:
> 
>> Quick additional question. Is it the --enable-debug configure flag 
>> that - normally - turns on the pov asserts? I've never verified this 
>> assumption of mine by creating a pov assert in the code I know should 
>> fail.
> 
> To be honest, I haven't a clue. I'm not sure what the `--enable-debug` 
> flag does exactly (it's some standard mechanism in the Automake tools), 
> nor whether and how assertions are enabled or disabled in Unix builds.
> 
> I'm pretty sure that `--enable-debug` does enable the creation of debug 
> information in the binaries, so that a debugging tool can correlate 
> binary code addresses with original source code lines, so that you can 
> e.g. set breakpoints and step through the code line by line with a 
> debugger. I also wouldn't be surprised if it turns off optimizations by 
> default, because those tend to re-order instructions and make a 
> line-by-line correlation impossible. Whether it does anything beyond 
> that I do not know. It might dictate whether `NDEBUG` is defined or not, 
> which would conceivably disable/enable assertions.

Back at it this morning.

First, flipping the file name compare so it's ahead of the file position 
compare (and assert) works fine too with all the test cases I have that 
fail.

Second, on enabling the POV_ASSERT source code mechanism, took the time 
to do some full compiles with a known fail assert of 1 == 0 and the 
short of it for *nix is doing something like:

./configure COMPILED_BY="wfp__POV_DEBUG" CXXFLAGS="-DPOV_DEBUG"

works. The -D<var> form on the define is added as a compiler flag to do 
the POV_DEBUG define, which, turns on the POV asserts that exist in the 
code (except I guess where not otherwise controlled or hard-set).

Lastly, on the --enable-debug flag, it is not today defining POV_DEBUG 
which is what turns on the POV_ASSERTs. Most of my actual debug compiles 
use a configure command like:

./configure COMPILED_BY="wfp" --disable-optimiz --disable-strip \ 
CXXFLAGS="-Og -ggdb fverbose-asm"

so --enable-debug isn't strictly needed for debugging though on line 
documentation I read just now indicates - by default anyway - it does 
something equivalent given certain arguments. Looks like you can select 
what sort of debugging gets turned on - and you can provide a second 
argument defining variables explicitly (ie POV_DEBUG) and there is the 
NDEBUG you mentioned (boost seems to use this some) getting set by 
default if the flag's argument turns debugging off (or the flag's not 
used but enabled?). What some documentation says only; Not sure what 
works or not for --enable-debug with our current set up without doing a 
bunch of compiles and tests. An investigation for another time. The flag 
doesn't control the POV_ASSERTs today via NDEBUG in any case - so at 
best it might provide another way to define POV_DEBUG using that second 
argument.

Bill P.


Post a reply to this message

From: William F Pokorny
Subject: Re: Parseerror:Uncategorizederrorthrownatparser/parsertypes.cppline62
Date: 29 Mar 2019 10:31:49
Message: <5c9e2c55$1@news.povray.org>
On 3/28/19 6:49 AM, William F Pokorny wrote:
> On 3/26/19 8:10 AM, clipka wrote:
...
> 
> Second, on enabling the POV_ASSERT source code mechanism, took the time 
> to do some full compiles with a known fail assert of 1 == 0 and the 
> short of it for *nix is doing something like:
> 
> ./configure COMPILED_BY="wfp__POV_DEBUG" CXXFLAGS="-DPOV_DEBUG"
> 
> works. 
...
> 

With the thought I might help others doing debug by rambling more about 
my ignorance/learning while attempting to debug this issue...

Woke up this morning remembering seeing a core file when I did my 
POV_ASSERT(1 == 0) test with a compile where POV_DEBUG was really 
defined. This got me wondering why I didn't get a core file with initial 
failing code here given an assert ran and I did a debug compile. A core 
file would have have made it easy to look at the call stack with gdb.

Well, looking at the source code this morning it's because we have this 
set up today for the parser related asserts in ./parser/configparser.h :

#ifndef POV_PARSER_DEBUG
     #define POV_PARSER_DEBUG POV_DEBUG
#endif

...

#if POV_PARSER_DEBUG
     #define POV_PARSER_ASSERT(expr) POV_ASSERT_HARD(expr)
#else
     #define POV_PARSER_ASSERT(expr) POV_ASSERT_SOFT(expr)
                                  // POV_ASSERT_DISABLE(expr)
#endif

I wasn't previously getting POV_DEBUG set so I was getting a soft assert 
which parse.cpp catches triggering a more graceful - but less 
informative (no core file) - program exit. Trying my debug compile again 
just now with POV_DEBUG set, I do get a core file and gdb gives me :

     ...
#4  0x000055a82da4b703 in pov_parser::LexemePosition::operator==
     o=...) at parser/parsertypes.cpp:62
#5  0x000055a82da40420 in pov_parser::Parser::IsEndOfInvokedMacro
     at parser/parser_tokenizer.cpp:964
#6  0x000055a82da44dcd in pov_parser::Parser::Get_Token
     at parser/parser_tokenizer.cpp:289
#7  0x000055a82da05cf7 in pov_parser::Parser::Parse_Frame
     at parser/parser.cpp:6559
#8  0x000055a82da06591 in pov_parser::Parser::Run
     at parser/parser.cpp:242
#9  0x000055a82d9cb3ef in pov::ParserTask::Run
     at backend/control/parsertask.cpp:81
...

Today, I'd find my way to IsEndOfInvokedMacro in less than an hour 
instead of the full day it took me to trace top down - so to speak.

The lessons I learned: Get POV_DEBUG set in your compile while debugging 
any issue. If still no core file generated and tangled in a POV-Ray code 
assert, be sure you're getting a hard assert and not a soft one. I 
didn't know we had 'soft' POV_ASSERT* version until today.

Bill P.


Post a reply to this message

From: William F Pokorny
Subject: Re: Parse error:Uncategorizederrorthrownatparser/parsertypes.cppline62
Date: 21 Mar 2020 13:07:09
Message: <5e7649bd$1@news.povray.org>
On 3/26/19 6:46 AM, William F Pokorny wrote:
> On 3/25/19 7:41 PM, clipka wrote:
>> Am 25.03.2019 um 23:55 schrieb clipka:
>>
>>> If `Cond_Stack.back().PMac->endPosition == CurrentFilePosition()` 
>>> throws an exception, it means either of two things:
>>>
>>> (A) The positions compared are from two different files, which means 
>>> the calling code has failed to check whether it is even in the right 
>>> file.
>>>
>>> (B) The line/column tracking is buggy, and yields different positions 
>>> in different situations.
>>
>>
>> Well, looking at the code of `IsEndOfInvokedMacro()` again, it 
>> _strongly_ reeks of scenario (A):
>>
>>      return (Cond_Stack.back().PMac->endPosition ==
>>                  CurrentFilePosition()) &&
>>             (Cond_Stack.back().PMac->source.fileName ==
>>                  mTokenizer.GetInputStreamName());
>>
>> should probably be swapped around, like so:
>>
>>      return (Cond_Stack.back().PMac->source.fileName ==
>>                  mTokenizer.GetInputStreamName()) &&
>>             (Cond_Stack.back().PMac->endPosition ==
>>                  CurrentFilePosition());
>>
>> so that the `LexemePosition` comparison operator is only invoked if 
>> the file names match.
>>
...

Documenting that Christoph's suggested code change up top, which fixed 
the bug with Warren's original test case and related test cases I 
created, is NOT in the v38 master branch as of commit 74b3ebe0 (March 8, 
2019).

Christoph - I think - planned to fix the core issue, but this has not 
happened as of today so the bug persists.

Bill P.


Post a reply to this message

<<< Previous 3 Messages Goto Initial 10 Messages

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.