The following active pattern doesn't use regular expression for better performance. However, it seems quite procedural style. Is it a better way to write in F#?
let (|Middle|_|) prefix postfix (input : string) =
if input.StartsWith(prefix) && input.EndsWith(postfix)
&& input.Length > prefix.Length + postfix.Length then
let len = input.Length - prefix.Length - postfix.Length
Some(input.Substring(prefix.Length, len))
else None
I think it's fine.
Why do you think it's not functional?
I would change only the last line in order to use string slices:
if input.StartsWith(prefix) && input.EndsWith(postfix)
&& input.Length > prefix.Length + postfix.Length then
Some(input.[prefix.Length .. input.Length - postfix.Length - 1])
else None
Anyway I don't think it makes it more functional.
Related
I have a series of string like this:
(((S|69|L || S|69|R || S|72|L || S|72|R) && ((S|62|L && (S|78|L || S|55|L) && (S|77|L || S|1|L)) || (S|62|R && (S|78|R || S|55|R) && (S|77|R || S|1|R)))) && (M|34|L || M|34|R) && (((M|40|L && M|39|L && M|36|L) || (M|40|R && M|39|R && M|36|R)) || ((M|38|L && M|36|L && M|37|L) || (M|38|R && M|36|R && M|37|R))))
And I need to run items that look like S|69|L to see if they satisfy this criteria. You can see that it's a series of && or || operations organized by parentheses.
I'm trying to use this tutorial: https://github.com/petitparser/dart-petitparser
But I'm having trouble getting off of the ground. Can anyone give me an example to get started with this? Maybe I just need more coffee...
Update: Making progress. This at least pulls off outside parentheses. I think I just need to continue to play with it, but I would still appreciate any tips for those who know how this works.
String testString = '((1||2) || 3)';
final inner = undefined();
final paren = (char('(').trim() & inner.star().flatten() & char(')').trim())
.map((values) => values[1]);
inner.set(paren | pattern('^)'));
final parser = inner.end();
final result = parser.parse(testString);
print(result.value);
The grammar you provide in the question seems to work for me and the provided example inputs pass.
A couple of tips:
If you are not interested in the parser output, instead of calling parser.parse(input) you could use parser.accept(input) to get a boolean.
Similarly, if you are not interested in the output, you can drop the calls to flatten() and map(...). Both are used to build an AST. Furthermore, flatten() hides the generated tree, which can make it hard to see what is happening.
For the actual values you could use a primitive parser like the following. However, not sure what your exact specification is?
final primitive = (uppercase() & char('|') & digit().plus() & char('|') & uppercase()).flatten().trim();
If you have the primitive parser, you can add an undefined parser for the logical expression (called outer) like so:
final outer = undefined();
final inner = undefined();
final operator = string('&&') | string('||');
outer.set(inner.separatedBy(operator));
final paren = char('(').trim() & outer & char(')').trim();
inner.set(paren | primitive);
final parser = outer.end();
Building expression parsers can get complicated and unwieldy quite quickly. With the Expression Builder this becomes much simpler:
final builder = ExpressionBuilder();
builder.group().primitive(primitive);
builder.group()
.wrapper(char('(').trim(), char(')').trim(), (l, v, r) => [l, v, r]);
builder.group()
..left(string('&&').trim(), (a, op, b) => [a, '&&', b])
..left(string('||').trim(), (a, op, b) => [a, '||', b]);
final parser = builder.build().end();
The program works fine with var dig = 0 and it doesn't work with var dig:Int I get an error: Variable "dig" used before being initialized Could you explain me why?
func myFunc(a:Int, b:Int) {
var c = a / b
var o = a % b
var v = 0
var dig = 0
if o != 0 {println("\(a)/\(b) = \(c) и \(o)/\(b)")}
else {println("\(a)/\(b) = \(c)")}
if a > b {
v = b
}
else {
v = a
}
for var i = 1; i <= v; ++i {
if a % i == 0 && b % i == 0 {dig = i}
}
println("\(dig) - greatest common denominator of \(a) and \(b)")
}
myFunc(27,81)
The only place you set the value of dig is inside of an if statement that is inside of a for loop. The Swift compiler does not know if the body of the for loop will be executed, and it doesn't know if the if statement will ever be true, so it has to assume that there is a path in which dig is not initialized.
Consider this simpler example:
func myFunc(a:Int, b:Int) {
var dig: Int
if a >= b {
dig = 3
}
if a < b {
dig = 4
}
println("\(dig) - greatest common denominator of \(a) and \(b)")
}
This example also gives the same error, because Swift considers each if separately. It is obvious to us that a is either greater than or equal to b or it is less than b, but Swift doesn't go that far in evaluating the situation. It just considers that each if may not be true, and dig is only set inside of ifs, so it is possible (as far as Swift is concerned) that dig may not be set.
func myFunc(a:Int, b:Int) {
var dig: Int
if a >= b {
dig = 3
} else {
dig = 4
}
println("\(dig) - greatest common denominator of \(a) and \(b)")
}
If you change the second condition to an else, Swift is then happy because it can reason that the if must be true or false and dig is set in each path, so it will certainly have a value before the println statement.
The compiler does not know mathematics good enough to
recognize that the statement
if a % i == 0 && b % i == 0 {dig = i}
is actually executed at least once (for i == 1). Therefore
the compiler assumes that dig might be undefined at
println("\(dig) - greatest common denominator of \(a) and \(b)")
Assigning an initial value in
var dig = 0
is the correct solution.
Btw., the Euclidean Algorithm is a much more effective method to
compute the greatest common divisor, see for example
http://rosettacode.org/wiki/Greatest_common_divisor#Swift.
I am writing code to ingest the IOR file generated by the team responsible for the server and use it to bind my client to their object. Sounds easy, right?
For some reason a bit beyond my grasp (having to do with firewalls, DMZs, etc.), the value for the server inside the IOR file is not something we can use. We have to modify it. However, the IOR string is encoded.
What does Visibroker provide that will let me decode the IOR string, change one or more values, then re-encode it and continue on as normal?
I've already looked into IORInterceptors and URL Naming but I don't think either will do the trick.
Thanks in advance!
When you feel like you need to hack an IOR, resist the urge to do so by writing code and whatnot to mangle it to your liking. IORs are meant to be created and dictated by the server that contains the referenced objects, so the moment you start mucking around in there, you're kinda "voiding your warranty".
Instead, spend your time finding the right way to make the IOR usable in your environment by having the server use an alternative hostname when it generates them. Most ORBs offer such a feature. I don't know Visibroker's particular configuration options at all, but a quick Google search revealed this page that shows a promising value:
vbroker.se.iiop_ts.host
Specifies the host name used by this server engine.
The default value, null, means use the host name from the system.
Hope that helps.
Long time ago I wrote IorParser for GNU Classpath, the code is available. It is a normal parser written being aware about the format, should not "void a warranty" I think. IOR contains multiple tagged profiles that are encapsulated very much like XML so we could parse/modify profiles that we need and understand and leave the rest untouched.
The profile we need to parse is TAG_INTERNET_IOP. It contains version number, host, port and object key. Code that reads and writes this profile can be found in gnu.IOR class. I am sorry this is part of the system library and not a nice piece of code to copy paste here but it should not be very difficult to rip it out with a couple of dependent classes.
This question has been repeatedly asked as CORBA :: Get the client ORB address and port with use of IIOP
Use the FixIOR tool (binary) from jacORB to patch the address and port of an IOR. Download the binary (unzip it) and run:
fixior <new-address> <new-port> <ior-file>
The tool will override the content of the IOR file with the 'patched' IOR
You can use IOR Parser to check the resulting IOR and compare it to your original IOR
Use this function to change the IOR. pass stringified IOR as first argument.
void hackIOR(const char* str, char* newIOR )
{
size_t s = (str ? strlen(str) : 0);
char temp[1000];
strcpy(newIOR,"IOR:");
const char *p = str;
s = (s-4)/2; // how many octets are there in the string
p += 4;
int i;
for (i=0; i<(int)s; i++) {
int j = i*2;
char v=0;
if (p[j] >= '0' && p[j] <= '9') {
v = ((p[j] - '0') << 4);
}
else if (p[j] >= 'a' && p[j] <= 'f') {
v = ((p[j] - 'a' + 10) << 4);
}
else if (p[j] >= 'A' && p[j] <= 'F') {
v = ((p[j] - 'A' + 10) << 4);
}
else
cout <<"invalid octet"<<endl;
if (p[j+1] >= '0' && p[j+1] <= '9') {
v += (p[j+1] - '0');
}
else if (p[j+1] >= 'a' && p[j+1] <= 'f') {
v += (p[j+1] - 'a' + 10);
}
else if (p[j+1] >= 'A' && p[j+1] <= 'F') {
v += (p[j+1] - 'A' + 10);
}
else
cout <<"invalid octet"<<endl;
temp[i]=v;
}
temp[i] = 0;
// Now temp has decoded IOR string. print it.
// Replace the object ID in temp.
// Encoded it back, with following code.
int temp1,temp2;
int l,k;
for(k = 0, l = 4 ; k < s ; k++)
{
temp1=temp2=temp[k];
temp1 &= 0x0F;
temp2 = temp2 & 0xF0;
temp2 = temp2 >> 4;
if(temp2 >=0 && temp2 <=9)
{
newIOR[l++] = temp2+'0';
}
else if(temp2 >=10 && temp2 <=15)
{
newIOR[l++] = temp2+'A'-10;
}
if(temp1 >=0 && temp1 <=9)
{
newIOR[l++] = temp1+'0';
}
else if(temp1 >=10 && temp1 <=15)
{
newIOR[l++] = temp1+'A'-10;
}
}
newIOR[l] = 0;
//new IOR is present in new variable newIOR.
}
Hope this works for you.
I'm trying to get Velocity to output the following Javascript code:
if ((whichOne+1) <= numCallouts ) {
whichOne = whichOne + 1; } else {
whichOne = 1;
}
Whenever I try to get Velocity to print a > or a <, it represents it as a & gt; or & lt;, which doesn't help me since I'm trying to get it to produce Javascript. I've tried:
#set ( $gt = ">" )
But even that ends up as a & gt;
Thanks in advance.
It is not a default behavior, the only reason I can think of why this is happening is if you have event ReferenceInsertionEventHandler configured with EscapeHtmlReference either in your velocity.config or in the Velocity initialization code.
Here is more info about events
I've had the same issue with Velocity - however, the problem is that I was using Velocity as an third party embedded language, and didn't have access to change the Velocity settings.
Unfortunately the only solution I was able to find was to rewrite the code without using greater than/less than explicitly, which admittedly is awful, but it's all about getting it to work...
Here is an example workaround for conditionals where you are trying to see if one number is larger than another:
if (n1 > n2) //Doesn't work because velocity turns this into if (n1 > n2)
if (n1 != n2)
{
diff = n1 - n2;
abs = abs(n1 - n2);
if (diff / abs == 1) //Greater than
else //if == -1 then less than
}
else //Equal
Maybe you are able to use the alternate symbols as described here :
http://velocity.apache.org/engine/devel/vtl-reference-guide.html#aifelseifelse_-_Output_conditional_on_truth_of_statements
So try to use if (n1 gt n2).
In Lua, using the = operator without an l-value seems to be equivalent to a print(r-value), here are a few examples run in the Lua standalone interpreter:
> = a
nil
> a = 8
> = a
8
> = 'hello'
hello
> = print
function: 003657C8
And so on...
My question is : where can I find a detailed description of this use for the = operator? How does it work? Is it by implying a special default l-value? I guess the root of my problem is that I have no clue what to type in Google to find info about it :-)
edit:
Thanks for the answers, you are right it's a feature of the interpreter. Silly question, for I don't know which reason I completely overlooked the obvious. I should avoid posting before the morning coffee :-) For completeness, here is the code dealing with this in the interpreter:
while ((status = loadline(L)) != -1) {
if (status == 0) status = docall(L, 0, 0);
report(L, status);
if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
lua_getglobal(L, "print");
lua_insert(L, 1);
if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
l_message(progname, lua_pushfstring(L,
"error calling " LUA_QL("print") " (%s)",
lua_tostring(L, -1)));
}
}
edit2:
To be really complete, the whole trick about pushing values on the stack is in the "pushline" function:
if (firstline && b[0] == '=') /* first line starts with `=' ? */
lua_pushfstring(L, "return %s", b+1); /* change it to `return' */
Quoting the man page:
In interactive mode ... If a line starts with '=', then lua displays the values of all the expressions in the remainder of the line. The expressions must be separated by commas.
I think that must be a feature of the stand alone interpreter. I can't make that work on anything I have compiled lua into.
I wouldn't call it a feature - the interpreter just returns the result of the statement. It's his job, isn't it?
Assignment isn't an expression that returns something in Lua like it is in C.