C#, ANTLR, ECMAScript grammar troubles - antlr3

I'm trying to parse JavaScript (ECMASCript) with C#.
I found the following instruction on how to create new project:
http://www.antlr.org/wiki/pages/viewpage.action?pageId=557075
So I've downloaded ANTLRWorks, ANTLR v3, unpacked ANTLR, created a VS2010 project (.NET4), added references, checked and generated the grammar.
Then I recieved a lot of compilation error:
The type or namespace name 'AstParserRuleReturnScope' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'GrammarRule' could not be found (are you missing a using directive or an assembly reference?)
Stackoverlowed for them and got a solution: antlr c# errors when integrating into VS2008
So I've downloaded new runtime, overwrite the old one and recompiled the project and got
The name 'HIDDEN' does not exist in the current context d:\Workspace.1\ScriptParser\ScriptParser\TestLexer.cs
Ok, I've changed HIDDEN to Hidden as recommended at in the following conversation: [antlr-interest] How viable is the Csharp3 target? (more specific questions)
Now I'm trying to parse the input. I found a few examples and wrote the following code:
using Antlr.Runtime;
namespace ScriptParser
{
class Program
{
static void Main(string[] args)
{
var stream = new ANTLRStringStream("1+2");
var lexer = new TestLexer(stream);
var tokenStream = new CommonTokenStream(lexer);
var parser = new TestParser(tokenStream);
// what exactly should be here???
}
}
}
My goal is to parser JavaScript file with ANTLR but it seems that it will be the not as easy as I thought...
Update:
As suggested in Why are antlr3 c# parser methods private? I've modified the Test.g grammar by adding the "public" modified before the expr rule:
public expr : mexpr (PLUS^ mexpr)* SEMI!
;
and then regenerated the code, replaced HIDDEN to Hidden (again) and modified the code as follows:
var stream = new ANTLRStringStream("1+2");
var lexer = new TestLexer(stream);
var tokenStream = new CommonTokenStream(lexer);
var parser = new TestParser(tokenStream);
var result = parser.expr();
var tree = (CommonTree)result.Tree;
And not it is crashing on the line
root_0 = (object)adaptor.Nil();
in the following generated code
try { DebugEnterRule(GrammarFileName, "expr");
DebugLocation(7, 0);
try
{
// d:\\Workspace.1\\ScriptParser\\ScriptParser\\Test.g:7:13: ( mexpr ( PLUS ^ mexpr )* SEMI !)
DebugEnterAlt(1);
// d:\\Workspace.1\\ScriptParser\\ScriptParser\\Test.g:7:15: mexpr ( PLUS ^ mexpr )* SEMI !
{
root_0 = (object)adaptor.Nil();
DebugLocation(7, 15);
PushFollow(Follow._mexpr_in_expr31);
with the NullReferenceException message because the adapter is null.
I've resolved it by adding
parser.TreeAdaptor = new CommonTreeAdaptor();
Update 2:
So, finally I've started with my primary task: parse JavaScript.
ANTLR highlights the ECMAScript grammar by Chris Lambrou.
So I've generated lexer/parser and run it with the very simple JavaScript code:
var f = function () { };
and the parsing fails with the following output from tree.ToStringTree():
<error: var q = function () { };>

Your grammar rule says that there should be a semicolon at the end of the expression, but in you main function:
var stream = new ANTLRStringStream("1+2");
is missing a semicolon. Shouldn't it be "1+2;"?

Related

Error on all Program.cs files on eShopOnContainers, microsoft microsevice based implmentation

Severity Code Description Project File Line Suppression State Error CS0260 Missing partial modifier on declaration of type 'Program'; another partial declaration of this type exists WebStatus D:\GitHub\eShopOnContainers\src\Web\WebStatus\Program.cs 123 Active
...
(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config)
{
var grpcPort = config.GetValue("GRPC_PORT", 5001);
var port = config.GetValue("PORT", 80);
return (port, grpcPort);
}
public class Program
{
public static string Namespace = typeof(Startup).Namespace;
public static string AppName
=Namespace.Substring(Namespace.LastIndexOf('.',Namespace.LastIndexOf('.') - 1) + 1);
}
this is the program found in Program.cs, look that it doesn't have a defined namespace, there are a bunch of functions defined as 'GetDefinedPorts'. I am following the Microsoft microservice implementation example https://github.com/dotnet-architecture/eShopOnContainers
This looks like a bug in Visual Studio 2022. It doesn't happen in 2019. They are also in the middle of converting the solution to dot net 6 so things may get a little more stable after that work is complete.

How to show Analyzer errors/warnings during msbuild in VS Dev Cmd & using MSBuildWorkspace

I'll explain the situation with an example.
Suppose I have created a Roslyn Analyzer which throws Error when Class name is TestClass. Analyzer code is as below:
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(Method, SyntaxKind.ClassDeclaration);
}
private static void Method(SyntaxNodeAnalysisContext context)
{
var node = (ClassDeclarationSyntax)context.Node;
var name = node.TryGetInferredMemberName();
if(name == "TestClass")
{
context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation()));
}
}
So i install the Analyzer nupkg in some ConsoleApp project. Console project has following code in Program.cs file
using System;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
class TestClass
{
static void test()
{
Console.WriteLine("TestClass");
}
}
}
Now if i build the ConsoleApp project in Visual Studio then i get Error as "TestClass name not to be used" which is fine.
But when i try to build the same project using msbuild command in Developer Command Prompt for VS 2017 i don't see any error from Analyzer. I want that all the errors shown in Error list in VS should be shown in Dev Cmd.
My end goal is to create a stand-alone code analysis tool project and then use MSBuildWorkspace to compile ConsoleApp project and get the analyzer errors/warnings. Part of code is as below:
var filePath = #"C:\Users\user\repos\ConsoleApp\ConsoleApp.sln";
var msbws = MSBuildWorkspace.Create();
var soln = await msbws.OpenSolutionAsync(filePath);
var errors = new List<Diagnostic>();
foreach (var proj in soln.Projects)
{
var name = proj.Name;
var compilation = await proj.GetCompilationAsync();
errors.AddRange(compilation.GetDiagnostics().Where(n => n.Severity == DiagnosticSeverity.Error).ToList());
}
var count = errors.Count();
Above code does not show errors/warnings from analyzer.
How can i achieve this?
Thanks in Advance.
To show analyzer errors/warnings during msbuild in VS Dev Cmd, you just have to pass rebuild switch for example
msbuild Tempsolution.sln /t:rebuild
And for MSBuidlWorkspace, this code worked for me. We have to manually specify the analyzer to use by using compilation.WithAnalyzer(ImmutableArray<DiagnosticAnalyzer>);.
MSBuildLocator.RegisterDefaults();
var filePath = #"C:\Users\user\repos\ConsoleApp\ConsoleApp.sln";
var msbws = MSBuildWorkspace.Create();
var soln = await msbws.OpenSolutionAsync(filePath);
var errors = new List<Diagnostic>();
foreach (var proj in soln.Projects)
{
var analyzer = proj.AnalyzerReferences.Where(alz => alz.Display.ToLower() == "Your analyzer name").FirstOrDefault();
var compilation = await proj.GetCompilationAsync();
var compWithAnalyzer = compilation.WithAnalyzers(analyzer.GetAnalyzersForAllLanguages());
var res = compWithAnalyzer.GetAllDiagnosticsAsync().Result;
errors.AddRange(res.Where(r => r.Severity == DiagnosticSeverity.Error).ToList());
}
var count = errors.Count();
How to show Analyzer errors/warnings during msbuild in VS Dev Cmd &
using MSBuildWorkspace
Actually, these warnings are from Code analysis mechanism rather than MSBuild warnings(like MSBxxx). And I think the TestClass name not to be used is just a warning(yellow mark) not an error.
In VS IDE, its environment integrates the MSBuild tool(Developer Command Prompt for VS) and Code Analyzer. Because of this, you can get the warnings in VS IDE.
However, when you use Developer Command Prompt, which is essentially a separate compilation tool for MSBuild, it doesnot have an integrated code analyzer, so you don't have this type of warning except for MSBuild warnings and errors(MSBxxx). This is also the limitation of the tool. Warning by itself does not affect the entire program.
Test
You can test it by input this in an empty console project: int a=1;(It is a code analyzer warning) and I am sure that the warning can be showed in output window in VS IDE and will not be listed in Developer Command Prompt for VS.
Suggestion
As a suggestion, you can try to treat these warnings as errors and Code Analyzer passes these warnings to the msbuild and specifies them as errors so that you can get the error in DEV.
Add these in your xxx.csproj file:
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
Although this approach breaks the build process, it is reliable and practical. And this method is very commonly used, generally used in the final production stage of the project, to exclude all errors and warnings for large projects, so as to prevent subsequent errors that may occur and be foolproof.
Then, you can use your code to build the project.

LINQ Extensions not available inside CSharpCodeProvider

I have a .NET application that can take a script written in C# and executes it internally. The scripts are parsed by the class listed below and then compiled. I find that whenever I try and use System.Xml.Linq in the C# script that is compiled I get a compile error and I am not sure why.
public static void CreateFunction(string scriptCode, BO.ObjectBO obj)
{
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters options = new CompilerParameters();
options.ReferencedAssemblies.Add("System.Data.dll");
options.ReferencedAssemblies.Add("System.dll");
options.ReferencedAssemblies.Add("System.Xml.dll");
options.ReferencedAssemblies.Add("System.Linq.dll");
options.ReferencedAssemblies.Add("System.Xml.Linq.dll");
options.GenerateExecutable = false;
options.GenerateInMemory = true;
CompilerResults results = provider.CompileAssemblyFromSource(options, scriptCode);
_errors = results.Errors;
if (results.Errors.HasErrors)
{
DataTable errorTable = BO.DataTableBO.ErrorTable();
foreach(CompilerError err in results.Errors)
{
DataRow dr = errorTable.NewRow();
dr["ErrorMessage"] = "Line "+ err.ErrorNumber.ToString() + " " + err.ErrorText;
errorTable.Rows.Add(dr);
}
return;
}
Type binaryFunction = results.CompiledAssembly.GetType("UserFunctions.BinaryFunction");
_methodInfo = binaryFunction.GetMethod("Function");
}
Here is the error message I get when I try and run a script that makes use of LINQ extensions inside the compiler.
'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>' could be found (are you missing a using directive or an assembly reference?)
Does anyone see what I may be doing wrong? I am attempting to include System.Linq and System.Xml.Linq yet the compiler does not seem to be able to locate them.
Here is an example C# script I am trying to compile that makes use of LINQ extensions.
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Xml.Linq;
namespace CompilerTest
{
public class BinaryFunction
{
public static void Function()
{
string xmlData = #"<data>
<clients>
<client>
<clientId>1</clientId>
<clientName>Dell</clientName>
</client>
<client>
<clientId>2</clientId>
<clientName>Apple</clientName>
</client>
</clients>
</data>";
XDocument xDoc = XDocument.Parse(xmlData);
List<string> results = xDoc.Descendants("data")
.Descendants("client")
.Select(x => x.Element("clientName").Value)
.ToList<string>();
}
}
}
UPDATE: I confirmed that the following assemblies were in the GAC. System.Xml and System.Xml.Linq. I also added the compiler version to the constructor and I still get the same error.
CSharpCodeProvider(new Dictionary<String, String> { { "CompilerVersion", "v4.6.1" } })
After searching for related errors I found the solution. I needed to add System.Core as a referenced assembly.
options.ReferencedAssemblies.Add("System.Core.dll");
Once I did this then the LINQ assemblies were used and I was able to use LINQ extensions. So to be clear my new code is
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters options = new CompilerParameters();
options.ReferencedAssemblies.Add("System.Data.dll");
options.ReferencedAssemblies.Add("System.dll");
options.ReferencedAssemblies.Add("System.Xml.dll");
options.ReferencedAssemblies.Add("System.Linq.dll");
options.ReferencedAssemblies.Add("System.Xml.Linq.dll");
options.ReferencedAssemblies.Add("System.Core.dll");
I am not sure why the reference to System.Core.dll is needed to be added as I would assume that it was referenced by default when creating a compiler instance but I guess not.

issues with the Geolocator xamarin plugin by James Montemagno

Hello I am working on a app in xamarin forms that needs to take the gps location and combine the latitude and longitude into a url for forcast.io i'm using the Geolocator plugin by James Montemagno and followed the readme but i'm still getting these errors:
Severity Code Description Project File Line Suppression State
Error CS0165 Use of unassigned local variable 'msi'
Severity Code Description Project File Line Suppression State
Error CS0266 Cannot implicitly convert type
'Plugin.Geolocator.Abstractions.IGeolocator' to
'Plugin.Geolocator.CrossGeolocator'. An explicit conversion exists
(are you missing a cast?)
Severity Code Description Project File Line Suppression State
Error CS1061 'CrossGeolocator' does not contain a definition for
'IsGeolocationEnabled' and no extension method 'IsGeolocationEnabled'
accepting a first argument of type 'CrossGeolocator' could be found
(are you missing a using directive or an assembly reference?)
Severity Code Description Project File Line Suppression State
Error CS1061 'CrossGeolocator' does not contain a definition for
'GetPositionAsync' and no extension method 'GetPositionAsync'
accepting a first argument of type 'CrossGeolocator' could be found
(are you missing a using directive or an assembly reference?)
Severity Code Description Project File Line Suppression State
Error CS1061 'CrossGeolocator' does not contain a definition for
'DesiredAccuracy' and no extension method 'DesiredAccuracy' accepting
a first argument of type 'CrossGeolocator' could be found (are you
missing a using directive or an assembly reference?)
and then here's the radar code:
using Xamarin.Forms;
using System;
using System.Diagnostics;
using Plugin.Geolocator;
namespace AppName.Radar
{
public interface MyLocationTracker
{
void ObtainMyLocation();
event EventHandler<MyLocationEventArgs> locationObtained;
}
public interface MyLocationEventArgs
{
double lat { get; set; }
double lng { get; set; }
}
public partial class RadarHome : ContentPage
{
private readonly CrossGeolocator _locator;
private double BetaLat;
private double BetaLog;
public RadarHome()
{
MyLocationTracker msi;
_locator = CrossGeolocator.Current;
if (_locator.IsGeolocationEnabled == false)
{
if (Device.OS == TargetPlatform.Android)
{
msi.locationObtained += (object Esender, MyLocationEventArgs ew) =>
{
Debug.WriteLine(ew.lat);
};
msi.ObtainMyLocation();
}
else if (Device.OS == TargetPlatform.iOS)
{
msi = DependencyService.Get<MyLocationTracker>();
msi.locationObtained += (object Jsender, MyLocationEventArgs je) =>
{
Debug.WriteLine(je.lat);
};
msi.ObtainMyLocation();
}
}
_locator.DesiredAccuracy = 50;
GetPositionAsynchronously();
string str = string.Format(
"https://forecast.io/?mobile=1#/f/Lat:{0} , Long: {1}", BetaLat, BetaLog);
var client = new System.Net.Http.HttpClient();
client.BaseAddress = new Uri(str);
}
private async void GetPositionAsynchronously()
{
//will run asynchronously in a diff thread
var position = await _locator.GetPositionAsync(timeoutMilliseconds: 100000);
BetaLat = position.Latitude; //will work
BetaLog = position.Longitude; // will work
}
}
}
I have the latest Geolocator nuget package installed on all 3 platforms (Froms, iOS, Android) I am using VS2015 update 3 and am still learning xamrarin forms so I'm sorry for asking such a noob question.
Thanks in advance!
Your _locator definition should look like this
private readonly IGeolocator _locator;
if (Device.OS == TargetPlatform.Android)
{
//You missed to resolve plugin there
msi = DependencyService.Get<MyLocationTracker>();
msi.locationObtained += (object Esender, MyLocationEventArgs ew) =>
{
Debug.WriteLine(ew.lat);
};
msi.ObtainMyLocation();
}
So both #William Corncob Decker, and #Greensy answers were correct
_locator definition needs to be: private readonly IGeolocator _locator;
and I did miss to resolve the msi plugin heres that code:
if (Device.OS == TargetPlatform.Android)
{
//You missed to resolve plugin there
msi = DependencyService.Get<MyLocationTracker>();
msi.locationObtained += (object Esender, MyLocationEventArgs ew) =>
{
Debug.WriteLine(ew.lat);
};
msi.ObtainMyLocation();
}
The only reason I'm doing this is because I can't mark both William Corncob Decker, and Greensy answers as correct so full credit goes to both of them!
Thank you guys again!

How to use SASS in Dart editor

Anyone have a canned solution for integrating SASS or another CSS preprocessor into the Dart editor? Seems to require a custom build.dart, which I would rather copy than code. Thanks.
I stumbled upon this a few days ago
Sass integration for pub
Here is a build.dart file with basic support for SASS:
import 'dart:io';
void main(List<String> args) {
for (String arg in args) {
if (arg.startsWith('--changed=')) {
String file = arg.substring('--changed='.length);
if (file.endsWith('.scss')) {
var result = Process.runSync('sass',
[ '--line-numbers', file,
file.substring(0, file.length - '.scss'.length) + '.css']);
if (result.exitCode != 0) {
// report error (SASS seems to only report first error)
// split error lines
var lines = result.stderr.split('\n');
// escape quotes in error message on first line
var error = lines[0].replaceAll('"', r'\"');
// extract line number from second line
var numMatch = new RegExp(r'\d+').firstMatch(lines[1]);
var lineNum = numMatch == null ? 1 : num.parse(numMatch.group(0));
// Report error via JSON
print('[{"method":"error","params":{"file":"$file","line":$lineNum,"message":"$error"}}]');
}
}
}
}
}
During development (with Dart Editor or another editor...), just use sass the way it's meant to be used, in your directory project :
sass -w .
Put the CSS generated files in the ignore list of your source code management system (aka .gitignore for git).
And for dart2js compilation, use the sass pub package : http://pub.dartlang.org/packages/sass

Resources