I have a REXX parameter string in this format:
arg = 'update summary(A summary of something) description(The description)'
and I'm parsing out the mode, summary and description as follows:
parse upper var arg mode . ,
1, 'SUMMARY('summary')' .,
1, 'DESCRIPTION('description')' .
I convert the arg to upper-case so that the SUMMARY and DESCRIPTION keywords are effectively case-insensitive (the user can code Summary or SUmmAry or sUmMaRy etc) but of course now I've just translated my actual summary and description to upper-case.
How can I make the parsing case-insensitive for the keywords, but keep the correct case for the actual parameters?
I've thought about extracting the character positions of the keywords and using them in the PARSE statement instead of '1' etc, but want a simple concise process if possible.
I came up with this 'toUpper' function, which is a bit simpler than expected. It takes a string and a list of words as input and returns the string with any of the words converted to upper case if found:
parms = 'UPdatE summary(The summary) Description(The description)'
say 'Parms are :' parms
parms = toUpper(parms, 'CHANGE UPDATE SUMMARY DESCRIPTION')
say 'Parms are now :' parms
exit
/********************************************************************/
/* Subroutines */
/********************************************************************/
toUpper:
parse arg string, wordList
stringUpper = string
upper stringUpper wordlist
do i = 1 to words(wordlist)
word = word(wordlist,i)
pos = pos(word, stringUpper)
if pos > 0 then string = overlay(word, string, pos)
end
return string
Output:
Parms are : UPdatE summary(The summary) Description(The description)
Parms are now : UPDATE SUMMARY(The summary) DESCRIPTION(The description)
This is a pretty common task when trying to simulate TSO-ish / IDCAMS-ish syntax in Rexx. I usually do something like this. It's such a short idiom, I never bother to make a subroutine out of it, just use it inline.
summary = 'Whatever the default value is'
description = 'Whatever the default value is'
parse var arg mode arg
mode = upper(mode)
do while arg <> ''
parse var arg keyword '(' value ')' arg
select upper(keyword)
when 'SUMMARY' then summary = value
when 'DESCRIPTION' then description = value
otherwise Say 'Unknown option:' keyword
end
end
As supplied Ross's code won't work on a z/OS system. The REXX on z/OS is a bit ancient. :-( The following codes will work.
summary = 'Whatever the default value is'
description = 'Whatever the default value is'
arg = 'UPdatE summary(The summary) Description(The description)'
parse var arg mode arg
upper mode
do while arg <> ''
parse var arg keyword '(' value ')' arg
upper keyword
select
when keyword='SUMMARY' then summary = value
when keyword='DESCRIPTION' then description = value
otherwise Say 'Unknown option:' keyword
end
end
Related
The string is like this:
TEMPLATES="!$TEMPLATE templatename manufacturer model mode\n$TEMPLATE MacQuantum Wash Basic\n$$MANUFACTURER Martin\n$$MODELNAME Mac Quantum Wash\n$$MODENAME Basic\n"
My way to get strings without tags is:
local sentence=""
for word in string.gmatch(line,"%S+") do
if word ~= tag then
sentence=sentence .. word.." "
end
end
table.insert(tagValues, sentence)
E(tag .." --> "..sentence)
And I get output:
$$MANUFACTURER --> Martin
$$MODELNAME --> Mac Quantum Wash
...
...
But this is not the way I like.
I would like to find first the block starting with $TEMPLATE tag to check if this is the right block. There is many such blocks in a file I read line by line. Then I have to get all tags marked with double $: $$MODELNAME etc.
I have tried it on many ways, but none satisfied me. Perhaps someone has an idea how to solve it?
We are going to use Lua patterns (like regex, but different) inside a function string.gmatch, which creates a loop.
Explanation:
for match in string.gmatch(string, pattern) do print(match) end is an iterative function that will iterate over every instance of pattern in string. The pattern I will use is %$+%w+%s[^\n]+
%$+ - At least 1 literal $ ($ is a special character so it needs the % to escape), + means 1 or more. You could match for just one ("%$") if you only need the data of the tag but we want information on how many $ there are so we'll leave that in.
%w+ - match any alphanumeric character, as many as appear in a row.
%s - match a single space character
[^\n]+ - match anything that isn't '\n' (^ means invert), as many as appear in a row.
Once the function hits a \n, it executes the loop on the match and repeats the process.
That leaves us with strings like "$TEMPLATE templatename manufacturer"
We want to extract the $TEMPLATE to its own variable to verify it, so we use string.match(string, pattern) to just return the value found by the pattern in string.
OK: EDIT: Here's a comprehensive example that should provide everything you're looking for.
templates = "!$TEMPLATE templatename manufacturer model mode\n$TEMPLATE MacQuantum Wash Basic\n$$MANUFACTURER Martin\n$$MODELNAME Mac Quantum Wash\n$$MODENAME Basic\n"
local data = {}
for match in string.gmatch(templates, "%$+%w+%s[^\n]+") do --finds the pattern given in the variable 'templates'
--this function assigns certain data to tags inside table t, which goes inside data.
local t = {}
t.tag = string.match(match, '%w+') --the tag (stuff that comes between a $ and a space)
t.info = string.gsub(match, '%$+%w+%s', "") --value of the tag (stuff that comes after the `$TEMPLATE `. Explanation: %$+ one or more dollar signs $w+ one or more alphanumeric characters $s a space. Replace with "" (erase it)
_, t.ds = string.gsub(match, '%$', "") --This function emits two values, the first one is garbage and we don't need (hence a blank variable, _). The second is the number of $s in the string).
table.insert(data, t)
end
for _,tag in pairs(data) do --iterate over every table of data in data.
for key, value in pairs(tag) do
print("Key:", key, "Value:", value) --this will show you data examples (see output)
end
print("-------------")
end
print('--just print the stuff with two dollar signs')
for key, data in pairs(data) do
if data.ds == 2 then --'data' becomes a subtable in table 'data', we evaluate how many dollar signs it recognized.
print(data.tag)
end
end
print("--just print the MODELNAME tag's value")
for key, data in pairs(data) do
if data.tag == "MODELNAME" then --evaluate the tag name.
print(data.info)
end
end
Output:
Key: info Value: templatename manufacturer model mode
Key: ds Value: 1
Key: tag Value: TEMPLATE
-------------
Key: info Value: MacQuantum Wash Basic
Key: ds Value: 1
Key: tag Value: TEMPLATE
-------------
Key: info Value: Martin
Key: ds Value: 2
Key: tag Value: MANUFACTURER
-------------
Key: info Value: Mac Quantum Wash
Key: ds Value: 2
Key: tag Value: MODELNAME
-------------
Key: info Value: Basic
Key: ds Value: 2
Key: tag Value: MODENAME
-------------
--just print the stuff with two dollar signs
MANUFACTURER
MODELNAME
MODENAME
--just print the MODELNAME tag's value:
Mac Quantum Wash
I am using torch.CmdLine() to parse command line arguments in Torch. I need to pass an array of elements for one of the variables. I am not aware of any mechanisms for passing an array of elements for a variable. So I am treating that variable as a string and passing the array of elements separated by space and enclosed within double quotes from the command line.
The code for doing this looks as follows:
cmd = torch.CmdLine()
cmd:text('Training')
cmd:text()
cmd:option('-cuda_device',"1 2 3")
params = cmd:parse(arg or {})
--parse the string to extract array of numbers
for i=1,string.len(params.cuda_device) do
if params.cuda_device[i] ~= ' ' then
-- some code here
end
end
Here since Lua string indexing is not provided by default, I had to override __index to enable indexing of string as follows,
getmetatable('').__index = function(str,i) return string.sub(str,i,i) end
This works for parsing the string to an array of numbers.
However, overriding __index breaks the code somewhere else, throwing the following error:
qlua: /home/torch/install/share/lua/5.1/torch/init.lua:173: bad argument #2 to '__index' (number expected, got string)
I can do some workarounds to fix this (instead of overriding __index use string.sub(str,i,i) directly) but I would like to know your suggestions in passing an array of elements using torch.CmdLine() in an elegant way--if applicable.
Thanks in Advance.
You can pass the list as a sequence of words separated by spaces as you have done, and after cmd:parse you can explode the string into an array using:
params = cmd:parse()
local tmptab = {}
for word in params.cuda_device:gmatch("%w+") do
tmptab[#tmptab +1] = word
end
params.cuda_device = tmptab
for i,v in pairs(params.cuda_device) do
-- some code here
end
That will explode the string parsed by cmd:parse() into an table with each word on it's on index, and there would be no need to delve into string metamethods...
Also, you can avoid the error doing this:
getmetatable('').__index = function(str,i)
if(type(i) == "number") then
return string.sub(str,i,i)
else
return ""
end
end
It is odd that you have tried to index a string using another string, however...
In my application I've got a procedure which should check if an input is valid or not. You can set up a regex for this input.
But in my case it returns false instead of true. And I can't find the problem.
My code looks like this:
gaps.each_index do | i |
if gaps[i].first.starts_with? "~"
# regular expression
begin
regex = gaps[i].first[1..-1]
# a pipe is used to seperate the regex from the solution-string
if regex.include? "|"
puts "REGEX FOUND ------------------------------------------"
regex = regex.split("|")[0..-2].join("|")
end
reg = Regexp.new(regex, true)
unless reg.match(data[i])
puts "REGEX WRONGGGG -------------------"
#wrong_indexes << i
end
rescue
end
else
# normal string
if data[i].nil? || data[i].strip != gaps[i].first.strip
#wrong_indexes << i
end
end
An example would be:
[[~berlin|berlin]]
The left one before the pipe is the regex and the right one next to the pipe is the correct solution.
This easy input should return true, but it doesn't.
Does anyone see the problem?
Thank you all
EDIT
Somewhere in this lines must be the problem:
if regex.include? "|"
puts "REGEX FOUND ------------------------------------------"
regex = regex.split("|")[0..-2].join("|")
end
reg = Regexp.new(regex, true)
unless reg.match(data[i])
Update: Result without ~
The whole point is that you are initializing regex using the Regexp constructor
Constructs a new regular expression from pattern, which can be either a String or a Regexp (in which case that regexp’s options are propagated, and new options may not be specified (a change as of Ruby 1.8).
However, when you pass the regex (obtained with regex.split("|")[0..-2].join("|")) to the constructor, it is a string, and reg = Regexp.new(regex, true) is getting ~berlin (or /berlin/i) as a literal string pattern. Thus, it actually is searching for something you do not expect.
See, regex= "[[/berlin/i|berlin]]" only finds a *literal /berlin/i text (see demo).
Also, you need to get the pattern from the [[...]], so strip these brackets with regex = regex.gsub(/\A\[+|\]+\z/, '').split("|")[0..-2].join("|").
Note you do not need to specify the case insensitive options, since you already pass true as the second parameter to Regexp.new, it is already case-insensitive.
If you are performing whole word lookup, add word boundaries: regex= "[[\\bberlin\\b|berlin]]" (see demo).
I'm still new to Xtext, so my apologies if this is a simple question.
I have a custom scripting language, that I am attempting to use XTEXT for syntax checking only. The language has one command per line, and has the format:
COMMAND:PARAMETERS
I have run into an issue when a parameter for a command is also a command keyword. The relevant part of the grammar file:
Model:
(commands += AbstractCommand)*
;
AbstractCommand:
Command1 | Command2
;
Command1:
command = 'command1' ':' value = Parameter
;
Command2:
command = 'command2' ':' value = Parameter
;
Parameter:
value = QualifiedParameter
;
QualifiedParameter:
(ID | ' ' | INT | '.' | '-' )+
;
The problem arises when one of the commands uses another another command as it's parameter. The rules of the language don't allow an actual 2nd command on the same line. In this case, it is just plain text that happens to have the same value as a pre-existing command. For example, assume Command1 and Command2 are expecting a complete sentence as it's parameter. Some sample valid commands would be:
Command1:This is a sentence
Command2:This is also a sentence
Command1:This sentence has Command2 in it
All 3 commands are valid, but the last line will generate an error "missing ":" at " ", because "Command2" has its own rules for parsing.
I've been reading the XTEXT documentation, and it seems like I can use first token set predicates to avoid reading the second token when the first is identified, but I cannot find any examples of this.
i am not sure if i get your question. maybe what you are looking for is the following:
Model: greetings+=Greeting*;
Greeting: "Hello" name=MyID "!";
MyID: "Hello" | ID;
this now allows to parse
Hello You!
Hello Hello!
Suppose I have a url
xyz.com/param1=abc¶m2=123¶m3=!##
Each parameter can have many values like:
param1 = abc, xyz, qwe
param2 = 123, 456, 789
param3 = !##, $%^, &*(
All the parameters and values will be read from an excel file. There can be n number of parameters and each may have any number of values.
I want to generate all the combinations which can be formed using all values of each parameters.
Output will be like:
xyz.com/param1=abc¶m2=123¶m3=!##
xyz.com/param1=xyz¶m2=456¶m3=!##
xyz.com/param1=qwe¶m2=123¶m3=!##
xyz.com/param1=qwe¶m2=456¶m3=!##
xyz.com/param1=xyz¶m2=789¶m3=$%^
...
..
and so on
besides the previous comment in your post, you need construct some nested loops.
I will assume you have a bash shell available (since you hadn't specified your wanted language).
for I in 'abc' 'xyz' 'qwe'
do
for J in '123' '456' '789'
do
for K in '!##' '$%^' '&*('
do
echo "xyz.com/param1=${I}¶m2=${J}¶m3=${K}"
done
done
done
Note that:
that '&*(' will bring you problems, since & is the character that you use to delimit each parameter.
double quotes " around echo, will make a double quote character to make this program to fail miserably
the same apply to ', \ and some others