Split lexer grammar files problems in C# - antlr4

I'm learning antlr. I've gotten it working with Java but can't get anything to work in C#. I've created the simplest case I can find using an example from The Definitive Antlr Book and I'm still getting problems.
Here is my code and my grammar. I've hardcoded "hello parr" as the input and get
line 1:6 mismatched input 'parr' expecting ID
PreParser.g4
grammar PreParser;
import PreParseLex;
r: 'hello' ID;
PreParserLex.g4
lexer grammar PreParseLex;
ID: [a-z]+;
WS: [ \t\r\n]+ -> skip ;
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Tree;
namespace PreparseApp
{
class Program
{
static void Main(string[] args)
{
string expression = "hello parr";
AntlrInputStream input = new AntlrInputStream(expression);
PreParseLex lexer = new PreParseLex(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
PreParserParser parser = new PreParserParser(tokens);
IParseTree tree = parser.r();
Console.WriteLine("Done");
}
}
}
I don't understand why 'parr' doesn't ID. Ideas?

Sam Harwell answered this question. I used the wrong class for the lexer in C#. I needed to use PreParseLexer rather than PreParseLex. See his full response.

Related

C#4.0 using static

I was given the following task and I am hoping that someone will be able to guide me in the right direction. Currently, we have code compiling in C#6. Due to varying reasons, some of my fellow coworkers are running C#4 and are unable to upgrade to C#6. I have to slightly alter the code so that it compiles for my coworkers.
In c#6, we have the following code:
using System;
using static SecGlobal.Constants;
with SecGlobal.Constants being:
namespace SecGlobal
{
public static class Constants
{
public const string CONST_DB_SERVER = "server name";
public const string CONST_MAIN_TIME_ZONE = "Eastern Standard Time";
... etc
}
}
The issue I run into is that the feature "using static" is not available in C#4. Are there any alternatives?
Just replace constant references with a fully qualified name. For instance,
using System;
using static SecGlobal.Constants;
...
string s = CONST_DB_SERVER;
...
Becoming
using System;
...
string s = SecGlobal.Constants.CONST_DB_SERVER;

Orchard: Add a wrapper to a shape in ShapeTableProvider ShapeTableBuilder

I have a shape named Account_UserDetails, that I'm trying to add some sort of wrapper to because it's just displaying as a bunch of LI's. I need a wrapper around the shape to control it better (like a UL). I tried the following but it doesnt seem to be showing in the browser at all. What am I doing wrong?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Orchard.DisplayManagement.Descriptors;
namespace Onestop.Themes.LOEH
{
public class ShapeDataProvider : IShapeTableProvider
{
public void Discover(ShapeTableBuilder builder)
{
builder.Describe("Account_UserDetails").OnDisplaying(context => {
context.Shape.Wrappers.Add("ul");
});
}
}
}
Wrappers in Orchard are shapes, you can add them as following:
builder.Describe("Account_UserDetails").OnDisplaying(context => {
context.Shape.Metadata.Wrappers.Add("Account_UserDetails_Wrapper");
});
Then you should add the wrapper shape as Account_UserDetails_Wrapper.cshtml:
<div>
#DisplayChildren(Model)
</div>
if you need more info about wrappers, please refer to this link

The name 'PropertySupport' does not exist in the current context

I would like to create a base class for observableObject generic enough for an observable object to derive from, but I hit some technical issue. This is an extract of the class. It is an abstract that implements interface INotifyPropertyChanged. But when I tried to use PropertySupport.ExtractPropertyName, I got compiler error saying 'PropertySupport' not exist in the current context. I am using VS2002. My intention was to create a library to host a small "framework" of my own and use it for different projects. Could anyone more well versed in the reflection point out what was wrong in my code to cause the compiler error?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace MyFramework
{
[Serializable]
public abstract class ObservableObject: INotifyPropertyChanged
{
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
var handler = this.PropertyChanged;
if (handler!=null)
{
handler(this, e);
}
}
protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression)
{
var propertyName = PropertySupport.ExtractPropertyName(propertyExpression);
this.RaisePropertyChanged(propertyName);
}
protected void RaisePropertyChanged(String propertyName)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
}
}
The error you are getting usually refers to a missing using directive or missing reference.
Looking at MSDN for the function you are trying to use it looks like you are missing the using directive Prism.ViewModel
using Microsoft.Practices.Prism.ViewModel;
If this doesn't fix your problem then you need to add a reference to the correct dll
Microsoft.Practices.Prism.Composition.dll
I've never used Prism but after copying your class, adding the correct reference & using directive it built ok.

I couldn't see my extension method

I couldn't see this method as extension method in MainWindow.xaml.cs , why
In MainWindow ,
I added :
using WpfApplication1_WPF.Classes;
please, advise me.
This is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Runtime.CompilerServices;
using System.Data.Objects;
namespace WpfApplication1_WPF.Classes
{
public static class Extensions
{
//1-Convert the user input to hash
public static String Hashed(String dataToHash)
{
//Convert dataToHash to byte array
byte[] plainTextBytes = Encoding.Unicode.GetBytes(dataToHash);
//Computer hash of bytes using SHA256 (256 bit hash value)
//Convert text to hash by using ComputerHash function in SHA256Managed algorithm
byte[] hash = new SHA256Managed().ComputeHash(plainTextBytes);
//Return hashed bytes as encoded string
//[convert hash byte to string to be saved in DB]
return Convert.ToBase64String(hash);
}
}
}
Add the following to the signarure
public static String Hashed(this String dataToHash)
You need the this in front of the input param.

How do you instantiate an object that is not included in your C# project?

Note: All sample code is greatly simplified.
I have a DLL defined as:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;
namespace RIV.Module
{
public interface IModule
{
StringWriter ProcessRequest(HttpContext context);
string Decrypt(string interactive);
string ExecutePlayerAction(object ParamObjectFromFlash);
void LogEvent(object LoggingObjectFromFlash);
}
}
Now, outside of my solution, other developers can define concrete classes and drop them into the BIN folder of my app. Maybe something like:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RIV.Module;
namespace RIV.Module.Greeting
{
public class Module : IModule
{
public System.IO.StringWriter ProcessRequest(System.Web.HttpContext context)
{
//...
}
public string Decrypt(string interactive)
{
//...
}
public string ExecutePlayerAction(object ParamObjectFromFlash)
{
//...
}
public void LogEvent(object LoggingObjectFromFlash)
{
//...
}
}
}
Now, in my app I would need to know that a new Module was available (I am guessing via web.config or something along those lines) and then be able to call it based off of some trigger in the database Campaign table (which maps to the module to use for that specific campaign).
I am trying to instantiate it this way:
var type = typeof(RIV.Module.Greeting.Module);
var obj = (RIV.Module.Greeting.Module)Activator.CreateInstance(type);
However, the compiler belches because a reference was never set to RIV.Module.Greeting.dll!
What am I doing wrong?
You need to use more reflection:
Load the assembly by calling Assembly.Load
Find the type by calling someAssembly.GetType(name) or searching someAssembly.GetTypes()
Pass the Type instance to Activator.CreateInstance
Cast it to your interface.
Instead of typeof(RIV.Module.Greeting.Module), try using
var type = Type.GetType("RIV.Module.Greeting.Module, RIV.Module.Greeting");
(i.e. load the type by specifying its assembly-qualified name as string) and casting to IModule.
This approach requires you to know the exact class and assembly names of the modules (as you wrote, they could be stored in web.config).
Alternatively, you could go for a completely dynamic plugin approach:
establish a convention that all module assemblies should be named "RIV.Module.XYZ"
scan the bin directory for matching DLLs
for each DLL, load it (e.g. Assembly.Load) and scan for types implementing IModule
instantiate all found types and cast to IModule

Resources