NCalc expression validation - c#

How can I validate NCalc expression? I want to use NCalc for evaluating if/else/endif condition in my simple custom language for defining sequence of steps. Main program will provide some parameters for conditions. Sequences are defined by user, so my parser have to validate if condition is ok and uses only provided parameters.
I already tried some tests, but don't know how to do this. HasErrors() methods doesn't check used parameters. Evaluate() uses optimalizations, so if I write expression "true or XXXX", it will end with true result and doesn't find out that XXXX parameter is invalid. How can I do this? I want to validate it already in compilation time.
Thanks.

I found the answer in this question (marked as answer), maybe I should have used also other keywords in google.
Get the parameters in an expression using NCalc
I tested that solution with my visitor based on LogicalExpressionVisitor and it's working. But, theoretically, maybe it's not the same as validation, because I get the list of parameter names, but from parsed expression, without supplied parameter values. So maybe the expression can fail in case of special "bad" parameter values supplied for evaluation. But it's enough for my case, I know all parameters I will supply to expression, so for me it's enough to get just parameter names.

Related

how to parse an expression step by step in c# (preferably visitor pattern)

I am new to c#. I have a question about parsing a string. If i have a file that contains dome lines such as PC: SWITCH_A == ON or a string like PC: defined(SWITCH_B) && SWITCH_C == OFF. All the operators(==, &&, defined) are string here and all the switch names(SWITCH_A) and their values are identifiers(OFF). How do i parse these kind of string? Do i first have to tokenize them split them by new lines or white spaces and then make an abstract syntax tree for parsing them? Also do i need to store all the identifiers in a dictionary first? I have no idea about parsing can anyone help? an tell me with an example how to do it what should be the methods and classes that should be included? Thanks.
Unfortunately, Yes. You have to tokenize them if the syntax that you are parsing is something custom and not a standard syntax where a compiler already exists for parsing the source.
You could take advantage of Expression Trees. They are there in the .NET Framework for building and evaluating dynamic languages.
To start parsing the syntax you have to have a grammar document that describes all the possible cases of the syntax in each line. After that, you can start parsing the lines and building your expression tree.
Parsing any source code typically goes a character at a time since each character might change the entire semantics of the piece that is being parsed.
So, i suggest you start with a grammar document for the syntax that you have and then start writing your parser.
Make sure that there isn't anything already out there for the syntax you are trying to parse as these kind of projects tend to be error-prone and time consuming
Now since your high-level grammar is
Expression ::= Identifier | IntegerValue | BooleanExpression
Identifier and IntegerValue are constant literals in the source, so you need to start looking for a BooleanExpression.
To find a BooleanExpression you need to look for either BooleanBinaryExpression, BooleanUnaryExpression, TrueExpression or FalseExpression.
You can detect a BooleanBinaryExpression by look for the && or == operators and then taking the left and right operands.
To detect a BooleanUnaryExpression you need to look for the word defined and then parse the identifier in the parantheses.
And so on...
Notice that your grammar supports recursion in the syntax, look at the definition of the AndExpression or EqualsExpression, they point back to Expression
AndExpression ::= Expression '&&' Expression
EqualsExpression ::= Expression '==' Expression
You got a bunch of methods in the String Class in the .NET Framework to assist you in detecting and parsing your grammar.
Another alternative is that you can look for a parser generator that targets c#. For example, see ANTLR

Regular Expression matching using Lambda Expressions

I am trying to implement a wildcard search Functionlity for (*,?) using LINQ to SQL. As of now, I want to try it using Regular expression as the code we write will be short and easily manageable. Here is what I have
string kw=_keyword.Replace("*",".*").Replace("?",".");
var predicate = PredicateBuilder.True<DAL.RequestAttribute>();
Regex reg=new Regex("^"+kw+"$");
predicate=predicate &&(reg.IsMatch(ra=>ra.AttributeValue));
So, here it gives a compilation error as "Cannot convert lambda expression to type 'string' because it is not a delegate type"
Though some workarounds if I make it compile and run, I get this runtime Error
"Method 'Boolean IsMatch(System.String)' has no supported translation to SQL."
So, I have two Questions here
1. Am I thinking in right lanes to implement my wildcard using Regular Expressions? if not, which is more efficient way to do this?
2. How to resolve this error .
Thanks
You could mimic SQL's LIKE operator by using SqlMethods.Like: https://msdn.microsoft.com/en-us/library/system.data.linq.sqlclient.sqlmethods.like%28v=vs.110%29.aspx.
Just be sure to use the appropriate wildcards/tokens: https://msdn.microsoft.com/en-us/library/ms179859.aspx.
Update:
You cannot use regular expressions with simple SQL. Since you are essentially building a SQL statement via LINQ, the same rule applies. Though, it's still not quite clear where you are tapping into LINQ with the sample code you've provided.
I would typically expect to see something like the following:
var results =
from Something in SomeLinqContext
where SqlMethods.Like(Something.Value, kw);
After some research I found an answer to my question. Thanks to Ventaur for the Suggestion. the solution is on similar lines but just a bit different. PFB the code for it
string kw=_keyword.Replace("*","%").Replace("?","_");
var predicate = PredicateBuilder.True<DAL.RequestAttribute>();
predicate = (ra => SqlMethods.Like(ra.AttributeValue, kw) && <Any other boolean conditions>
Therefore it boils down to how to make an expression out of SQLMethods.like method using our predicate builder class.

How to convert a search string to a boolean condition?

I have a search criteria stored in a string:
string Searchstr = "(r.Value.Contains("PwC") || (r.Value.Contains("Canadian") && r.Value.Contains("thrive"))) || (r.Value.Contains("Banana") && r.Value.Contains("Gayle"))"
I want to use this in a If statement to check the values:
if(searchstr)
{
then do this....
}
but the if should have a searchstr as boolean.
How to convert this to boolean?
EDIT: The requirement is to give search criteria dynamically in a text box in the following format - "PwC OR (Canadian AND thrive)".
Which will be used to search an XML file.
Therefore I have loaded an XML file and want to have a Where condition in LINQ for which I need to use Dynamic LINQ but string is not allowed in that and also I have some braces to deal with.
Thinking of that I have taken the resultset from the XML(The tag value which i need to search)
var selectedBook = from r in document.Root.Descendants("Archives").Elements("Headline").Elements("Para")
select r;
and would ideally like to try something like:
var query=selectedbook.Where(searchstr)
OR
if(searchstr){....then do this}
You will need to do a bit of work to make this happen, but it is possible.
You should have a look at the dynamic LINQ library. This allows you to specify LINQ conditions (and other clauses) as strings and execute them just like LINQ operators.
Start with the explanation on ScottGu's blog and follow the links:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
I'm assuming the string is going to reference only a specific set of objects (r or r.Value in this case, for example - or anything else you want, as long as you know it beforehand). If this is the case, then:
Create a delegate that takes the objects (that may be referenced) as parameters
and returns a bool, as you want.
Programmatically write a small C# source file in memory that defines the query
as the body of a method (with a fixed name, preferably) that conforms to the delegate specified above.
Use the CSharpCodeProvider class to compile an assembly
with your custom function that returns the bool you want.
Run the dynamically written and compiled code from your main program.
Well as you may guess it is not going to be straight forward but at the same time it is not as hard a problem as it seems
You can perform a few steps to get what you want:
Get the search expression as input (for e.g. "PwC OR (Canadian AND thrive)")
Write an extension method on XElement that returns true and takes the search criteria as input. You will then be able to use
var selectedBook = from r in
document.Root.Descendants("Archives").Elements("Headline").Elements("Para")
where r.SatisfiesCriteria(searchCriteria)
select r;
Write a parser class that parses searchCritera and stores it in parsed format. (for e.g. you can convert it into postfix notation). This is quite easy and you can use standard algorithm for this. For your purpose OR, AND will be operators and PwC etc. will be operands. Parenthesis will get removed as part of parsing.
Now simply invoke this parser from with in your extension method and then evaluate the postfix expression you get. This again can be done through standard stack based evaluation. Infact it would be better if you parse the criteria once and then only evaluate in where. While evaluating you need to replace the operands with r.Value.Contains
It seems like a good scenario for http://scriptcs.net/

Can I add a regular expression into a .Net Assertion?

I'm trying to pull out page source from a set of pages and run an assertion on the results, this is a Test that runs to check that we are crawling specific pages in our site. Sometimes the results come back with a different case for the URL string, I'd like to account for that in the Assertion where I am checking page source. This is probably the wrong way to do this but I was wondering if there is a way to add in the .Net regex commands to the Assertion text. I have this as an assertion:
Assert.IsTrue(driver.PageSource.Contains("/explore"));
But is there a way to be sure that I can capture explore, Explore or EXPLORE? I though I could use (?i) here but that doesn't seem to work. I'm more used to Perl and it's regex capabilities but with C# and .Net I'm a little lost on where I can and can't use the inline regex commands.
Anthonys answer is valid, you don't really need regex. But if you do want to use it, you can use
Regex.IsMatch(driver.PageSource, "/explore", RegexOptions.IgnoreCase)
You don't need a regular expression to perform a case-insensitive check. Use IndexOf and compare that the result is greater than -1. IndexOf has overloads that allow you to specify if casing matters. Something like
bool containsExplore = driver.PageSource.IndexOf("/explore", StringComparison.InvariantCultureIgnoreCase) > -1;
Assert.IsTrue(containsExplore);
Try:
RegEx.Match("string", "regexp", RegExOptions.IgnoreCase).Success
How about using
StringAssert.Matches(string, regex);
In your case, that would translate to
StringAssert.Matches("drive.PageSource", "\/explore");

Regex index in matching string where the match failed

I am wondering if it is possible to extract the index position in a given string where a Regex failed when trying to match it?
For example, if my regex was "abc" and I tried to match that with "abd" the match would fail at index 2.
Edit for clarification. The reason I need this is to allow me to simplify the parsing component of my application. The application is an Assmebly language teaching tool which allows students to write, compile, and execute assembly like programs.
Currently I have a tokenizer class which converts input strings into Tokens using regex's. This works very well. For example:
The tokenizer would produce the following tokens given the following input = "INP :x:":
Token.OPCODE, Token.WHITESPACE, Token.LABEL, Token.EOL
These tokens are then analysed to ensure they conform to a syntax for a given statement. Currently this is done using IF statements and is proving cumbersome. The upside of this approach is that I can provide detailed error messages. I.E
if(token[2] != Token.LABEL) { throw new SyntaxError("Expected label");}
I want to use a regular expression to define a syntax instead of the annoying IF statements. But in doing so I lose the ability to return detailed error reports. I therefore would at least like to inform the user of WHERE the error occurred.
I agree with Colin Younger, I don't think it is possible with the existing Regex class. However, I think it is doable if you are willing to sweat a little:
Get the Regex class source code
(e.g.
http://www.codeplex.com/NetMassDownloader
to download the .Net source).
Change the code to have a readonly
property with the failure index.
Make sure your code uses that Regex
rather than Microsoft's.
I guess such an index would only have meaning in some simple case, like in your example.
If you'll take a regex like "ab*c*z" (where by * I mean any character) and a string "abbbcbbcdd", what should be the index, you are talking about?
It will depend on the algorithm used for mathcing...
Could fail on "abbbc..." or on "abbbcbbc..."
I don't believe it's possible, but I am intrigued why you would want it.
In order to do that you would need either callbacks embedded in the regex (which AFAIK C# doesn't support) or preferably hooks into the regex engine. Even then, it's not clear what result you would want if backtracking was involved.
It is not possible to be able to tell where a regex fails. as a result you need to take a different approach. You need to compare strings. Use a regex to remove all the things that could vary and compare it with the string that you know it does not change.
I run into the same problem came up to your answer and had to work out my own solution. Here it is:
https://stackoverflow.com/a/11730035/637142
hope it helps

Categories