Problems porting lexer string accumulator to new version of Quex - c++

While porting my lexer file from Quex 0.64.8 to 0.67.4 I ran
into some problems with the string accumulator. The issues
I get look like this:
Severity Code Description Project File Line Suppression State
Error C3861 'ecmascript_lexer_Accumulator__clear': identifier not found (compiling source file C:\Users\Patrikj\Work\git\ecmascript_build_vc14_x64\generated\ecmascript_lexer.cpp) ktes C:\Users\Patrikj\Work\git\ecmascript\ecmascript.qx 107
I suppose it's the double underline Accumulator__clear that is the cause of the issue. Maybe I need to supply a new switch to Quex or maybe the API
has changed in the newer version. Either way I am at a loss on how to
fix the issue.
And example from my lexer (.qx) that generates the issue:
mode StringHelper : EOF
<inheritable: only>
{
on_exit {
/// All 3 rows using the accumulator generates an error similiar to the one mentioned above
if(self.accumulator.text.begin != self.accumulator.text.end)
self_send(TOK_STRLITPART);
self_accumulator_flush(TOK_QUOTE);
self_accumulator_clear();
}
}
Any help fixing this issue would be much appreciated.
Best regards,
Patrik J

Version 0.67.3 and later excluded the string accumulator from
the main generator. The reason was that for some situations
there is no general solution in the construct, include-push,
and reset scenarios. Users must specify them as they go along.
For using the accumulator, no command line option is required.
However, in the .qx files the following sections need to be defined
(this is an example):
header {
#include <quex/code_base/extra/accumulator/Accumulator>
}
footer {
#include <quex/code_base/extra/accumulator/Accumulator.i>
}
body {
QUEX_NAME(Accumulator) accumulator;
}
constructor {
if( ! QUEX_NAME(Accumulator_construct)(&me->accumulator, me) ) {
return false;
}
}
destructor {
QUEX_NAME(Accumulator_destruct)(&me->accumulator);
}
print {
QUEX_NAME(Accumulator_print_this)(&me->accumulator);
}
The case with the PostCategorizer is the same. You find the setup
shown below in 'common.qx' files in the demo subdirectories.
Also, after 'flush()' you do not need to 'clear()'.

Related

Is there any way to make Visual Studio C++ error output useful?

I find VS19 output quite useless when working on C++ project. Consider running the example code on freshly installed VS19:
#include <iostream>
using namespace std;
class My
{
public:
void f() noexcept
{
throw exception{"A problem sir!"};
}
};
int main()
{
try
{
My m;
m.f();
}
catch (exception& ex)
{
cout << "exception caught! " << ex.what() << endl;
}
return 0;
}
What I would like to receive is: "Function throws an exception while marked as noexcept", and the cursor set on the problematic line. What I get is a new window with some general text, none of which mentions the problem, or where the problem is.
What compiler warning level have you specified? If I use the /W0 option there is no diagnostic but with any other value, /W1 through /W4, the compiler outputs the following lines:
1>filename.cpp(9,1): warning C4297: 'My::f': function assumed not to throw an exception but does
1>filename.cpp(9,1): message : __declspec(nothrow), throw(), noexcept(true), or noexcept was specified on the function
Note: the diagnostic messages include the line and column numbers. If you double-click the error message it moves the cursor to the offending line.
Your verbosity parameter of MSBuild is may be too high. Go to menu: Tools -> Options. Then on the left pane select: Projects and Solutions -> Build and Run.
There you can select the appropriate verbosity of MSBuild (from Quiet to Diagnostic)
Trying to resolve your puzzle in your question:
What I get is a new window with some general text, none of which
mentions the problem, or where the problem is.
I find 90% of output useless for me.
I think what you mean is the Output window, it is always used to display output about build process.
Also, You can also program your own applications to write diagnostic messages at run time to an Output pane. To do this, use members of the Debug class or Trace class in the System.Diagnostics namespace of the .NET Framework Class Library.
For those large solution or large project, which has plenty of resource files. The build sometimes fail with unknown error. The output window is necessary for trouble-shooting.
If you think most of its info is useless,like P.PICARD suggests: Go Tools=>Projects and Solutions=>Build and Run to set its build output verbosity(!Not build log file verbosity) I suggest you change it to Minimal.
If you have a failed build and want to watch the details of the whole build process. Change it to Detailed and rebuild the project or solution.
What I would like to receive is: "Function throws an exception while
marked as noexcept", and the cursor set on the problematic line.
Have you checked the Error List window? If it disappeared,choose View > Error List, or press Ctrl++E.
Add two lines to your code sample:
int main()
{
int a = 2;
int b;
...
}
Navigate to the Error List window(I suggest you set it as Build and Intellisense):
I think it's what you want. And error list window also indicates the Variable which is not initialized or not referenced for improving your coding.
Also, you can see their line numbers. And Double-click the error message, the cursor will navigate to that line.
For C++ program, the warning level is from w0 to w4, you can set it w4 to get the high warning level.(By default it should be w3)
Right-click project=>properties=>Configuration Properties=>C/C++=>Warning Level to set it. (Have been described by Blastfurance, thanks to him!)
Change it to w0, nothing shows. Change it to w3, and it will show warnings about My::f and b but not a.(Actually I don't think you make changes to that, because w3 is by default) Change it to w4 then get the high warning level and all associated warnings display.

HXCPP Profiler won't create log file

I am using Haxe for a game and compiling for the C++ target using HXCPP. I am trying to get the built-in profiler to work (cpp.vm.Profiler), but I cannot get it to create a dump file. My code is as simple as that :
if(Input.check(Key.P))
cpp.vm.Profiler.start("profiler.txt");
if(Input.check(Key.M))
cpp.vm.Profiler.stop();
I use HaxePunk for the input, and I assert that the profiler calls are indeed being executed (I made sure using a couple trace calls). I use defines HXCPP_STACK_TRACE and HXCPP_PROFILER for the compilation.
Am I doing anything wrong, or missing anything ?
EDIT : here is some code that when compiled using haxe -D HXCPP_PROFILER -D HXCPP_STACK_TRACE -main Main -cpp test, doesn't actually create any noticeable "profiler.txt" file :
class Main
{
static public function main()
{
var bleh = haxe.Timer.stamp();
cpp.vm.Profiler.start("profiler.txt");
while(haxe.Timer.stamp() - bleh < 5.)
{
// Do something I guess
Math.cos(haxe.Timer.stamp());
}
cpp.vm.Profiler.stop();
}
}
Relevant bug report to hxcpp: #580.
Apparently this was fixed on 17 May 2017 in this commit. The fix should be in the next hxcpp version after 3.4.64.

Function definitions missing from intellisense in Visual Studio C++ 2005-2013

The following problem plagues one of my projects for a long time:
Some function definitions (from .cpp files) are excluded/hidden from intellisense!
It is not possible to "Goto Definition" for those functions, nor are the listed in the Navigation Bar.
The functions do appear in the autocompletion list, though. The problem is for .cpp files only, the .h files are parsed fine. 'Goto Declaration' works, too.
This is the same since 2005, with every new version, I was hoping for a fix, but it does not seem to be regognized as a bug by anyone else.
UPDATE:
I have tracked this down to the following: All functions containing a certain macro are not recognized by intellisense. The original macro was
#define forlist(x,list) for( auto x= list.begin(); x.valid(); ++x)
but you can also use the simplified test case
#define fortest(x) for( auto x= 1; x< 2; ++x)
void myclass::TestFN()
{
fortest( g )
{
g;
}
}
Next step would be to find a workaround (or try to go through micrsoft bug reporting).
Please don't rant too much about this macro. This is existing code of a list implementation which I am not able to change. I could just NOT use the macro, but I still think this is a VS bug.
One funny thing is, that the following (really ***ic macro) works fine:
#define fortest(x) for( auto x= 1; x< 2; ++x) {
void myclass::TestFN()
{
fortest( g )
g;
}
}
Could it be that intellisense treats case 1 as an illegal local function definition?
(see http://connect.microsoft.com/VisualStudio/feedback/details/781121/c-intellisense-mistakes-loop-expression-for-function-definition)
The following work fine, too
#define fortest(x) for( auto x= 1; x< 2; ++x)
void myclass::TestFN()
{
fortest( g )
g;
}
As usual, interest in my question ebbed up after a couple of hours, so I had to figure it out by myself...
We just have to use the concept of cpp.hint files.
Basically you have to put the troublesome macros into a file named cpp.hint and put that file in your solution directory (which did not work for me)
OR in a parent-directory where your code files reside in. (worked for me)
In that file we just put the troublesome macros WITHOUT right-hand-side, so e.g.:
#define forlist(x,list)
NOTE: Your must reset IntelliSense cache for use new data from changed cpp.hint file. You should:
delete ipch folder (usually placed in Solution folder).
delete all *.sdf files in Solution folder.
delete all *.VC.db files in Solution folder or in ipch folder.
For more advanced macros (like having 'start' and 'end' macros for code blocks), there are some other tricks.
The original link is:
http://msdn.microsoft.com/en-us/library/dd997977.aspx
The reason for the trouble is that Intellisense performance would (potentially) decrease dramatically if it had to parse all macros in a project, so it only parses those given explicitly in 'cpp.hint'.

Can I programmatically collapse/expand all preprocessor blocks of a certain name in Visual Studio 2012?

My current project has a lot of debug preprocessor blocks scattered throughout the code. These are intentionally named differently to the system _DEBUG and NDEBUG macros, so I have a lot of this:
// Some code here
#ifdef PROJNAME_DEBUG
//unit tests, assumption testing, etc.
#endif
// code continues
These blocks sometimes get rather large, and their presence can sometimes inhibit code readability. In Visual Studio 2012 I can easily collapse these, but it would be nice to automatically have all of them collapsed, allowing me to expand them if I want to see what's in there. However, as I also have a bunch of header guards I don't want to collapse all preprocessor blocks, only the #ifdef PROJNAME_DEBUG ones.
Can I do this?
This is the most easiest scenario you can achive it, I think.
You should create an Add-In first in C#. (in VS 2013 they become deprecated :( )
In the OnConnection method you should add your command:
public void OnConnection( object application, ext_ConnectMode connectMode, object addInInst, ref Array custom )
{
_applicationObject = (DTE2)application;
if (connectMode == ext_ConnectMode.ext_cm_AfterStartup || connectMode == ext_ConnectMode.ext_cm_Startup)
{
Commands2 commands = (Commands2)_applicationObject.Commands;
try
{
//Add a command to the Commands collection:
Command command = commands.AddNamedCommand2(_addInInstance, "MyAddinMenuBar", "MyAddinMenuBar", "Executes the command for MyAddinMenuBar", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);
}
catch (System.ArgumentException)
{
//If we are here, bla, bla... (Auto generated)
}
}
}
Note: you can find how parameters are act at the reference of AddNamedCommand2
The template created version would be also fine, but naturaly it worth to name your command properly.
After that you need to add your logic to Exec method:
public void Exec( string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled )
{
handled = false;
if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if (commandName == "MyAddinMenuBar.Connect.MyAddinMenuBar")
{
List<string> args = (varIn as string).Split(' ').ToList();
TextSelection ts;
ts = (TextSelection)_applicationObject.ActiveDocument.Selection;
EditPoint ep = (ts.ActivePoint).CreateEditPoint();
ep.StartOfDocument();
do
{
string actualLine = ep.GetLines(ep.Line, ep.Line + 1);
if (args.TrueForAll(filter => actualLine.Contains(filter)))
{
_applicationObject.ExecuteCommand("Edit.GoTo", ep.Line.ToString());
_applicationObject.ExecuteCommand("Edit.ToggleOutliningExpansion");
}
ep.LineDown();
} while (!ep.AtEndOfDocument);
handled = true;
return;
}
}
}
Note: Name you given to the command is checked in exec.
Than you can build.
Deployment of Add-In can happen through an [ProjectName].AddIn file in ..\Documents\Visaul Studio 20[XY]\AddIns\. (Created by the template, you should copy if you move the Add-In elsewhere)
You should place your Add-In assembly where the Assembly element of the mentioned file you set to point. To change version you should modify the text in Version element.
After you deployed and started Studio, you should activate the Add-In in the manager in Toolsmenu.
You need to expand all collapsable section in your code file (CTRL+M+L with C# IDE settigs).
This is required because I found only a way to invert the state of collapsion. If you find better command, you can change it.
Next you should activate Command Window to use the the created command.
Now only you need to type your commands name, like this:
MyAddinMenuBar.Connect.MyAddinMenuBar #ifdef PROJNAME_DEBUG
Hopefully magic will happen.
This solution is independent of language of code you edit so pretty multifunctional.

Is there any way to make Visual Studio stop indenting namespaces?

Visual Studio keeps trying to indent the code inside namespaces.
For example:
namespace Foo
{
void Bar();
void Bar()
{
}
}
Now, if I un-indent it manually then it stays that way. But unfortunately if I add something right before void Bar(); - such as a comment - VS will keep trying to indent it.
This is so annoying that basically because of this only reason I almost never use namespaces in C++. I can't understand why it tries to indent them (what's the point in indenting 1 or even 5 tabs the whole file?), or how to make it stop.
Is there a way to stop this behavior? A config option, an add-in, a registry setting, hell even a hack that modifies devenv.exe directly.
As KindDragon points out, Visual Studio 2013 Update 2 has an option to stop indenting.
You can uncheck TOOLS -> Options -> Text Editor -> C/C++ -> Formatting -> Indentation -> Indent namespace contents.
Just don't insert anything before the first line of code. You could try the following approach to insert a null line of code (it seems to work in VS2005):
namespace foo
{; // !<---
void Test();
}
This seems to suppress the indentation, but compilers may issue warnings and code reviewers/maintainers may be surprised! (And quite rightly, in the usual case!)
Probably not what you wanted to hear, but a lot of people work around this by using macros:
#define BEGIN_NAMESPACE(x) namespace x {
#define END_NAMESPACE }
Sounds dumb, but you'd be surprised how many system headers use this. (glibc's stl implentation, for instance, has _GLIBCXX_BEGIN_NAMESPACE() for this.)
I actually prefer this way, because I always tend to cringe when I see un-indented lines following a {. That's just me though.
Here is a macro that could help you. It will remove indentation if it detects that you are currently creating a namespace. It is not perfect but seems to work so far.
Public Sub aftekeypress(ByVal key As String, ByVal sel As TextSelection, ByVal completion As Boolean) _
Handles TextDocumentKeyPressEvents.AfterKeyPress
If (Not completion And key = vbCr) Then
'Only perform this if we are using smart indent
If DTE.Properties("TextEditor", "C/C++").Item("IndentStyle").Value = 2 Then
Dim textDocument As TextDocument = DTE.ActiveDocument.Object("TextDocument")
Dim startPoint As EditPoint = sel.ActivePoint.CreateEditPoint()
Dim matchPoint As EditPoint = sel.ActivePoint.CreateEditPoint()
Dim findOptions As Integer = vsFindOptions.vsFindOptionsMatchCase + vsFindOptions.vsFindOptionsMatchWholeWord + vsFindOptions.vsFindOptionsBackwards
If startPoint.FindPattern("namespace", findOptions, matchPoint) Then
Dim lines = matchPoint.GetLines(matchPoint.Line, sel.ActivePoint.Line)
' Make sure we are still in the namespace {} but nothing has been typed
If System.Text.RegularExpressions.Regex.IsMatch(lines, "^[\s]*(namespace[\s\w]+)?[\s\{]+$") Then
sel.Unindent()
End If
End If
End If
End If
End Sub
Since it is running all the time, you need to make sure you are installing the macro inside in your EnvironmentEvents project item inside MyMacros. You can only access this module in the Macro Explorer (Tools->Macros->Macro Explorer).
One note, it does not currently support "packed" namespaces such as
namespace A { namespace B {
...
}
}
EDIT
To support "packed" namespaces such as the example above and/or support comments after the namespace, such as namespace A { /* Example */, you can try to use the following line instead:
If System.Text.RegularExpressions.Regex.IsMatch(lines, "^[\s]*(namespace.+)?[\s\{]+$") Then
I haven't had the chance to test it a lot yet, but it seems to be working.
You could also forward declare your types (or whatever) inside the namespace then implement outside like this:
namespace test {
class MyClass;
}
class test::MyClass {
//...
};
Visual Studio 2017+
You can get to this "Indent namespace contents" setting under Tools->Options then Text Editor->C/C++->Formatting->Indention. It's deep in the menus but extremely helpful once found.
I understand the problem when there are nested namespaces. I used to pack all the namespaces in a single line to avoid the multiple indentation. It will leave one level, but that's not as bad as many levels. It's been so long since I have used VS that I hardly remember those days.
namespace outer { namespace middle { namespace inner {
void Test();
.....
}}}