How can I get Lexer and Parser with ANTLR for C#? - c#

Seems ANTLR support C# language but I dont know how I can generate related class.
I searched and saw exists an Extention for Visual Studio but I does not support 2015
so How I can generate Lexer and Parser for C# with ANTLR manually ?

The VS extension mainly serves for syntax highlighting and editor niceties. It's quite useful but you can still live without it (IIRC a change in VS2015 prevents a compatible release).
What you should do is use the Antlr4 NuGet package, which will automate the generation of parsers. It will run ANTLR at compile-time.
If you do have the VS extension (in VS2013 for instance), just add a new ANTLR grammar file to your project and you're done.
But if you don't have the extension, you'll have to set up the project manually. Here are the steps to make it work:
Install the NuGet package:
Add a new text file to the project, name it with a .g4 extension
Save, and then unload the project from the project's context menu in the solution explorer:
Reload it:
Select your .g4 file in the solution explorer, go to the Properties window, and set the Build Action to Antlr4:
Edit your file, for instance:
grammar MyLanguage;
compileUnit: 'Hello' EOF;
Go to File -> Advanced Save Options and choose UTF8 without signature or the ISO-8859-1 encoding (ANTLR just doesn't handle UTF8 with BOM):
Build your project, your new classes will be available
You can now write some code:
var lexer = new MyLanguageLexer(new AntlrInputStream("Hello"));

No need for integration with visual studio.
Download the jar file here: http://www.antlr.org/download/antlr-runtime-4.5.1.jar
Save it to C:\Test
Add the jar to your classpath:
Using System Properties dialog > Environment variables > Create or append to CLASSPATH variable
In the variable, put C:\Test\antlr-runtime-4.5.1.jar If values already exist for this variable, insert a ; before your new entry
Copy in your grammar file to C:\Test
Go to the command line, navigate to C:\Test
Create your 'outputdirectory' folder, and run this (remember to replace {outputdirectory} and {input}:
java org.antlr.v4.Tool -o -visitor -no-listener -Werror -o {outputdirectory} -Dlanguage=CSharp {input}.g4

Related

VS 2022 - Convert to file-scoped namespace in all files

I'm converting my project to .NET 6 and I want to use filescoped namespaces everywhere. But the conversion tool exists only in the editor.
Has anyone found out if there's a way to run this editor function across all files in solution at once? (Looks like Rider has that function)
Adding a rule to use file scoped namespaces in .editorconfig worked for me:
create an .editorconfig file in the solution directory
add following line/content below (docs, code - IDE0161)
Example .editorconfig file content:
[*.cs]
csharp_style_namespace_declarations = file_scoped:warning
After that the preview changes dialog had an option to apply the fix to the whole project/solution:
I always have problems finding files that are supposed to be updated (.editorconfig in this case). I don't even know if I should search for it in the project's, Visual Studio installation's or any folder on the PC. So I like the answer in the link below because it says where in the interface to change the setting.
Best answer in my opinion is here:
https://www.ilkayilknur.com/how-to-convert-block-scoped-namespacees-to-file-scoped-namespaces
It says that you can change the code-style preference (and enable the display of the option to apply this preference in a document / project / solution) by going to Tools => Options => Text Editor => C#=> Code Style and then changing the related preference.
EditorConfig syntax
csharp_style_namespace_declarations = file_scoped:error
dotnet_diagnostic.IDE0161.severity = error
Note
Syntax option = rule:severity will be deprecated, sooner or later.
I strongly recommend to read this article before you start build .editorconfig for your project.
After you have configured the .editorconfig, you can configure a 'Code Cleanup' setting to automatically convert all files to use file-scoped namespace. Go to Tools -> Options -> Text Editor -> Code Cleanup -> Configure Code Cleanup. Then add the 'Apply namespace preferences'. Then go to Analyze -> Code Cleanup (or just search for 'Code cleanup') and run the Code Cleanup to automatically change the namespaces to file-scoped.

Updated custom generated files on save

In a .xaml file as soon as I add a new control, I am able to reference it for the xaml.cs file because VS is kind enough the generate the C# code for it in a g.i.cs file.
For example
In MainWindow.xaml I add
<Grid>
<Button x:Name="Test"/>
</Grid>
I am able to access it from MainWindow.xaml.cs like
this.Test.Content = "TestButton";
Because VS generated MainWindow.g.i.cs in the obj folder which contains
internal System.Windows.Controls.Button Test;
I have been able to have exactly the same behavior using msbuild for a custom file .xyz which is a designer view for a .cs file. I've have created a msbuild target that regenerates the .cs files on build and on project load but I'm not able to do the same thing on file save
Now my questions:
How does VS regenerate the g.i.cs on save ?
Is this a VS feature or an msbuild one ?
Can I trigger an incremental build on save?
Update:
I've also looked through a WPF .csproj and it uses the same .targets files as a class library C# project. The only differences I could spot are the DependentUpon and the SubType item metadata
How does VS regenerate the g.i.cs on save ?
AFAIK, Visual Studio invoke the XAML compiler xamlc.exe to compile the XAML files regenerate the g.i.cs on save.
Check this blog Understanding In and Out of XAML in WPF:
In the blog, the author said that compilation of XAML happened in 2 steps:
Step 1. The first step is to compile the XAML files into BAML using the xamlc.exe compiler. For example, if our project includes a file name Window1.xaml, the compiler will create a temporary file named Window1.baml and place it in the obj\Debug subfolder (in our project folder). At the same time, a partial class is created for our window, using the language of our choice. For example, if we’re using C#, the compiler will create a file named Window1.g.cs in the obj\Debug folder. The g stands for generated.
Step 2. When the XAML-to-BAML compilation stage is finished, Visual
Studio uses the appropriate language compiler to compile our code and
the generated partial class files. In the case of a C# application,
it’s the csc.exe compiler that handles this task. The compiled code
becomes a single assembly Window1.exe) and the BAML for each window is
embedded as a separate resource.
.
Is this a VS feature or an msbuild one?
This should be Visual Studio feature. As I said above, Visual Studio invoke the XAML compiler xamlc.exe to compile the .xaml files on save. Visual Studio will invoke MSBuild to compile the those file to .exe/.dll on build. Besides, when you on save not build the project, you can open your Task Manager, there is no MSBuild.exe exists, only when you build the project, it will comes up. So this should be Visual Studio feature not MSBuild on save.
Can I trigger an incremental build on save?
In the Visual Studio, the build system provides support for incremental builds. But if you want trigger an incremental build with your a custom MSBuild file .xyz, I am afraid you could not do that, because MSBuild only works on Build not save.
The [!INCLUDETLA2#tla_wpf] build system provides support for incremental builds. It is fairly intelligent about detecting changes made to markup or code, and it compiles only those artifacts affected by the change. The incremental build mechanism uses the following files
Check the Building a WPF Application (WPF) for more details.
Hope this helps.

how to add a new c# file to a project using dotnet-cli

I'm learning how to use dotnet-cli with VSCode. I've seen many commands on how to create solution, projects, add reference to projects... but I don't see anywhere in the documentation how to add a file. If remember, in RubyOnRails it was possible to add file from the command line.
Thanks for helping
Not that I know of (I was also researching that topic) but I found helpful extension for VS code called C# Extensions by jchannon, which helps you create classes and interfaces with correct namespace by right-clicking the folder in VS code explorer and selecting to create C# class or C# interface.
If you’re after plain old C# classes then yeah, I’m not aware of cli support. However, VS Code can create classes with the “right” namespaces by right-clicking on a folder and selecting Add new class (or somesuch).
However the dotnet aspnet-codegenerator can create boilerplate classes for various elements of an MVC application. Here is a discussion.
Just add the file in the same directory or sub-directory then build the project using Core CLI, it will be added.
As per the Core CLI documentation by default all the source files are included in the build, without being added into the project files, though there are option available to override this default behaviour.
Visual Studio has an UX that allows you to right-click a project or a folder underneath a project and open a context window. Selecting Add brings up a modal that allows you to select a file template. This intelligently adds the corresponding file to the location specified, adding a calculated namespace and default using statements that are typical for that file type. These item templates are backed by .vstemplate files and complemented by a file of that type. For example, for a C# class, there is a Class folder with a Class.cs file and a Class.vstemplate file. The former is a template for a C# file, the latter is an XML-based file that describes the template, per the XML namespace described here. This is a starting point.
According to Tutorial: Create a project template for dotnet new,
With .NET Core, you can create and deploy templates that generate projects, files, even resources. This tutorial is part two of a series that teaches you how to create, install, and uninstall, templates for use with the dotnet new command. [emphasis added]
This blog post, How to create your own template for dotnet new, has some examples how to add replaceable parameters and optional content, which would be good for adding namespaces, class names, class keywords, etc.
Based on this information, my next step would be to try and create some dotnet new file templates. After the basics of creating a file, I would then experiment with how to make them smarter, like these VS Templates, using replaceable parameters and optional content.
just type
new-item YourCSharpFileName.cs
i know this is not your point but; this simple answer must stay here
this powershell command doesn't create a templated csharp class but; if you like or find easier to add a new file just by typing. powershell, command prompt or any terminal... it could be very helpfull. add your file than configure the others(namespace, usings...)
additionaly for git bash use touch YourFileName.cs
i hope this help someone. if anything wrong please comment me.
Install the template first
dotnet new --install Yae.Templates
Then you can use
dotnet new class -t filename -o foldername
I used to use the plugin C# Extensions which is no longer under development. Today I found a replacement extension for the new class/interface functionality called "C# Stretch": https://marketplace.visualstudio.com/items?itemName=jacokok.csharp-stretch
Its a context-menu item in the file explorer allowing you to type in a class name. It produces a C# file with an empty class with the namespace declared in the new file-scoped manner. The nesting namespace format is available as an option in settings.
dotnet new provides many templates like mvc, webapp, classlib, etc. but doesn't provide templates for class, interface, struct, etc. ...
I searched and found that we can install these templates using command
dotnet new -i Yae.Templates::0.0.2
and then you can use command in your preferred directory
dotnet new class -t <nameOfClass_without_extension_.cs>

VS2013 - How to pass the solution folder, $(SolutionDir), in the command line arguments for a C# project using an external program

I am building a C# adding for Excel. In order to debug it, I need to launch Excel.exe with a command line argument containing the Debug or Release path to the addin.
For example:
Start External Program: C:\Program Files\Microsoft Office\Office15\EXCEL.EXE
Command line argument "C:\Dev\Project1\Project1\bin\Debug\Project1-AddIn64.xll"
However, I would like to replace "C:\Dev\Project1\Project1\bin\Debug" with an equivalent of $(SolutionDir) for C++ projects in VS. Is there a way to do this ? If it is not doable, is there a way to get around this ?
EDIT: please support me and get this added in VS by voting up the following idea: http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/6350738-support-for-macros-in-debugging-command-line-argum
Indeed, the macros cannot be used in the Start Options | Command line arguments
I see two solutions:
As the current folder is set to the $(TargetDir) when you Start an application you could refer to the solution folder like this: ..\..\..\ if the External program accepts a relative path. (I am not quite sure why you would ever want to refer to the solution folder, referring to the output/target folder makes more sense to me)
In the Post Build event (unregister) and register the component the way the component should be registered when deploying it (a proper setup). This way you only have to refer to Excel in the Start Action. This also immediately adds the benefit of testing a scenario that is more similar to production.
It's not exactly a fix, but this may help some people. If you create your project from the project template "Visual C#/.NET Core/Console App" instead of "Visual C#/Windows/Console App", this feature is supported. When I put "$(SolutionDir)" in the Application Arguments field on the Debug tab of the Project Properties window, it is expanded at run time. Note that you will need Visual Studio 2015 Update 3 or later.
I guess you could make use of post-build event to read in your file. #HansPassant explained it in VS2010 - Project Macro Variables in Start Options Command Line Arguments.
A short quote:
A possible workaround is a post-build event that writes a file that you read in your program. Like echo $(ProjectName) > "$(TargetDir)cmdargs.txt
You could substitute cmdargs.txt to appropriate file you want.
You CAN use the macros in the Command fields. I used procmon.exe to see what VS was looking for and indeed i could use $(SolutionDir)\..\Debug\thetoolname.exe as my solution was not in the root.
Im using VS2019 so AFAIK it is supported from this version but it most likely is supported in lower versions. Just use procmon to check the path that VS is attempting to resolve.

Antlr4 C# targets and output path of generated files

I have a C# solution with an Antlr3 grammar file, and I'm trying to upgrade to Anltr4. It turns out the grammar was the easy part (it became better, and one third the size!). Generating the parser turned out to be the tricky part.
In the old solution I merely ran AntlrWorks to update the lexer and parser .cs files when the grammar file changed. The lexer and parser were included directly in the same project as the grammar so the framework around the parser could make use of them directly.
With the Antlr4 targets for C# I noticed that (at least by default) the output path of the generated Parser C# classes is in the intermediate directory, e.g. obj\Debug. This means I can't use the parser directly in the same project. Am I supposed to change the output path if I want the generated source usable in my sln? Don't I want it in my sln?
I tried making a separate project for the parser generation, that is, a project containing only the grammar file. When this project is built using the Antlr4 targets, the resulting assembly can be referenced from projects needing the parser classes. However, if this project is included in the solution I still don't get any intellisense in visual studio since it bases its intellisense on source files for loaded projects, so it is still not quite usable. The only way I could get it working properly was to build then unload the parser project, and have other projects reference it as an assembly file rather than a project.
EDIT:
After looking on the antlr-interest list I found this thread indicating that the problem with intellisense may be Resharpers fault. If this is the case, then my question is rather how to keep using both Antlr4 and Resharper in my solution?
https://groups.google.com/forum/#!topic/antlr-discussion/QSuJXphaBDg
I found an extension for Resharper: ReSharper.ExternalCode.
Tip for Antlr: add obj\Debug in Resharper -> Code Inspection -> External Code and reload solution.
It's works for me.
There is an easy way to get the best of both Antlr 4 and Visual Studio. You are on the right track in having a separate grammar project and implementation project, but you are missing a couple steps.
Follow these steps to get the Intellisense working
In Visual Studio, go to Tools -> Extensions and Updates and search the Online section for "ANTLR Language Support" by Sam Harwell.
This does a few things:
Adds Templates for the combined grammars.
Adds Syntax Highlighting
Adds an MSBuild target for the grammar to generate the parser.
In your solution, set up your project structure like this:
Solution
Grammar Project
ANTLR 4 Combined Grammar
Implementation Project
Folder for Links to Generated files
Listener Implementation Class
Write and Compile your grammar.
In your folder for the Links to Generated Files, Right-Click the folder and click Add -> Existing Item
Browse to Grammar Project\obj\Debug and select all the generated parser files.
This next step is important. On the Add button there is a little drop-down arrow. Click the drop-down arrow and click "Add As Link".
This will add the generated files to the implementation project using a symbolic link instead of a direct copy.
This gives the added benefit of not having to remove and re-add the parser files if you have to change your grammar later.
Intellisense should work now for your generated parser classes, and you don't
even have to disable ReSharper.
You are encountering a known bug with ReSharper. The ANTLR 3 and ANTLR 4 C# build integration is reliable, and uses long-established patterns that Microsoft uses with other languages and code generation tasks. Your options are:
Stop using ReSharper
Get the ReSharper authors to address the lack of support for this feature, or
Modify the ANTLR 4 target to work around the limitation in ReSharper, which will introduce other problems into the build which may or may not be acceptable for your use.
Option 1 is certainly the least expensive, and most likely to provide reliable long-term support for your projects.

Categories

Resources