Token matching order in PLY - ply

I have a parser written in PLY that has the following token definition
def t_COMMAND(t):
r'create|show'
return t
def t_SCOPE(t):
r'user|domain'
return t
def t_STRING(t):
r'[a-zA-Z_#\*\.]*'
return t
I am trying to parse the following string
show user where created_on = foo
Here is my grammar
S:COMMAND SCOPE FILTER;
FILTER:WHERE EXP |;
EXP:STRING OP STRING
...
I get a syntax error at the created_on token, probably because it gets matched as a COMMAND rather than STRING
Is there a way to make PLY take the largest possible match?

Found two possible approaches
User a reserved words tuple and append it with the token list as in Specification of tokens
If possible, add quotes to the STRING as '[a-zA-Z_#\*\.]*', so that it can be distinguished from COMMAND
I chose the second approach, as I have a lot of so called reserved words.

Related

How to extract a substring from main string starting from valid uuid using lua

I have a main string as below
"/tmp/xjtscpdownload/7eb17cc6-b3c9-4ebd-945b-c0e0656a33f0/output/9999.317528060546245771146821638997525068657/"
From the main string i need to extract a substring starting from the uuid part
"/7eb17cc6-b3c9-4ebd-945b-c0e0656a33f0/output/9999.317528060546245771146821638997525068657/"
I tried
string.match("/tmp/xjtscpdownload/7eb17cc6-b3c9-4ebd-945b-c0e0656a33f0/output/9999.317528060546245771146821638997525068657/", "/[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}/(.)/(.)/$"
But noluck.
if you want to obtain
"/7eb17cc6-b3c9-4ebd-945b-c0e0656a33f0/output/9999.317528060546245771146821638997525068657/"
from
"/tmp/xjtscpdownload/7eb17cc6-b3c9-4ebd-945b-c0e0656a33f0/output/9999.317528060546245771146821638997525068657/"
or let's say 7eb17cc6-b3c9-4ebd-945b-c0e0656a33f0, output and 9999.317528060546245771146821638997525068657 as this is what your pattern attempt suggests. Otherwise leave out the parenthesis in the following solution.
You can use a pattern like this:
local text = "/tmp/xjtscpdownload/7eb17cc6-b3c9-4ebd-945b-c0e0656a33f0/output/9999.317528060546245771146821638997525068657/"
print(text:match("/([%x%-]+)/([^/]+)/([^/]+)"))
"/([^/]+)/" captures at least one non-slash-character between two slashs.
On your attempt:
You cannot give counts like {4} in a string pattern.
You have to escape - with % as it is a magic character.
(.) would only capture a single character.
Please read the Lua manual to find out what you did wrong and how to use string patterns properly.
Try also the code
s="/tmp/xjtscpdownload/7eb17cc6-b3c9-4ebd-945b-c0e0656a33f0/output/9999.317528060546245771146821638997525068657/"
print(s:match("/.-/.-(/.+)$"))
It skips the first two "fields" by using a non-greedy match.

Case insensitive token matching

Is it possible to set the grammar to match case insensitively.
so for example a rule:
checkName = 'CHECK' Word;
would match check name as well as CHECK name
Creator of PEGKit here.
The only way to do this currently is to use a Semantic Predicate in a round-about sort of way:
checkName = { MATCHES_IGNORE_CASE(LS(1), #"check") }? Word Word;
Some explanations:
Semantic Predicates are a feature lifted directly from ANTLR. The Semantic Predicate part is the { ... }?. These can be placed anywhere in your grammar rules. They should contain either a single expression or a series of statements ending in a return statement which evaluates to a boolean value. This one contains a single expression. If the expression evaluates to false, matching of the current rule (checkName in this case) will fail. A true value will allow matching to proceed.
MATCHES_IGNORE_CASE(str, regexPattern) is a convenience macro I've defined for your use in Predicates and Actions to do regex matches. It has a case-sensitive friend: MATCHES(str, regexPattern). The second argument is an NSString* regex pattern. Meaning should be obvious.
LS(num) is another convenience macro for your use in Predicates/Actions. It means fetch a Lookahead String and the argument specifies how far to lookahead. So LS(1) means lookahead by 1. In other words, "fetch the string value of the first upcoming token the parser is about to try to match".
Notice that I'm still matching Word twice at the end there. The first Word is necessary for matching 'check' (even though it was already tested in the predicate, it was not matched and consumed). The second Word is for your name or whatever.
Hope that helps.

TALES expression to compare numeric input in Plone?

TALES expression is new to me. Can I get some good reference for the same? Actually I wish to define a content rule for numeric input field using ploneformgen. Something like:
python: request.form.get('amt', False) <= 5000
then apply the rule.
Here 'amt' is a numeric/whole number field on the input form.
For reference, you should look at the official TALES specification, or refer to the TALES section of the Zope Page Templates reference.
In this case, you are using a plain python expression, and thus the normal rules of python code apply.
The expression request.form.get('amt', False) would return the request parameter 'amt' from the request, and if that's missing, return the boolean False, which you then compare to an integer value.
There are 2 things wrong with that expression: first of all you assume that the 'amt' parameter is an integer value. Even a PFG integer field however, is still a string in the request object. As such you'll need to convert in to an integer first before you can compare it.
Also, you fall back to a boolean, which in integer comparisons will be regarded as the equivalent of 0, better be explicit and use that instead:
python: int(request.form.get('amt', 0)) <= 5000
Note that for a PFG condition, you can also return a string error message instead of boolean True:
python: int(request.form.get('amt', 0)) <= 5000 or 'Amount must be not be greater than 5000'
Usually form parameters are passed in as strings if they are not defined on the application level otherwise e.g.
Zope will under the hood use the fieldname amt:int in order to convert the value to an integer.
So you may want to try to put an int(....) around the first expression.

ActiveXObject("Shell.Application") - how to pass arguments with spaces?

I run exe from my asp.net with JavaScript using ActiveXObject. It runs successfully, except parameters:
function CallEXE() {
var oShell = new ActiveXObject("Shell.Application");
var prog = "C:\\Users\\admin\\Desktop\\myCustom.exe";
oShell.ShellExecute(prog,"customer name fullname","","open","1");
}
Example, I pass that like parameters,[1] customer name,[2] fullname, but after space character, Javascript perceive different parameter.
How can I fix?
ShellExecute takes the 2nd parameter to be a string that represents all the arguments and processes these using normal shell processing rules: spaces and quotes, in particular.
oShell.ShellExecute(prog,"customer name fullname",...)
In this case the 3 parameters that are passed are customer, name, fullname
oShell.ShellExecute(prog,"customer 'a name with spaces' fullname",...)
As corrected/noted by Remy Lebeau - TeamB, double-quotes can be used to defined argument boundaries:
oShell.ShellExecute(prog,'customer "a name with spaces" fullname',...)
In this case the 3 parameters that are passed are customer, a name with spaces, fullname
That is, think of how you would call myCustom.exe from the command-prompt. It's the same thing when using ShellExecute.
Happy coding.
Try escaping your spaces with a backslash. The cmd.exe cd command does this, maybe you'll get lucky and it'll work here as well...
oShell.ShellExecute(prog,"customer a\ name\ with\ spaces fullname", ...)

asp.net regex help

Hi ive got this regular expression and that extracts numbers from a string
string.Join(null,System.Text.RegularExpressions.Regex.Split(expr, "[^\\d]"));
so eg, the format of my string is like this strA:12, strB:14, strC:15
so the regex returns 121415
how can I modify the expression to return
12,14,15 instead, any suggestions please
You're calling String.Join, which joins an array of strings into a single string, separating each element by the separator parameter.
Since you're passing null as that parameter, it doesn't put anything between the strings.
You need to pass ", " instead of null to separate each string with ,.

Resources