CPN Tools - Exception compile is raised with aborted parsing - ml

I am generating a Message Sequence Chart (MSC) to my model. I have the following code in the transition and it is working:
input (p_id, p_cert, v_id, v_cert);
action
MSC.addEvent(msc, p, i, func_to_concat(p_id, p_cert));
if v_cred(p_id, p_cert, v_id, v_cert) then
MSC.addEvent(msc, i, p, "Some message here.")
else
MSC.addEvent(msc, i, p, "Some other message.")
I tested this code and it worked fine. Then, I decided to put it into a function, that is coded as follows:
fun a(msc, e, i, id, cert, v_id, v_cert) =
MSC.addEvent(msc, i, e, func_to_concat(id, cert));
if v_cred(id, cert, v_id, v_cert) then
MSC.addEvent(msc, i, e, "Some message here.")
else
MSC.addEvent(msc, i, e, "Some other message.")
But I am receiving this error message:
Error: Error: exception Compile is raised with Aborted parsing
Can anyone suggest something to solve this problem?

Problem solved. In order to specify a command block in ML language, we have to put the code inside parentheses:
fun a(msc, e, i, id, cert, v_id, v_cert) = (
MSC.addEvent(msc, e, i, func_to_concat(id, cert));
if v_cred(id, cert, v_id, v_cert) then
MSC.addEvent(msc, i, e, "Some message here.")
else
MSC.addEvent(msc, i, e, "Some other message.")
)

Related

Can an iOS native interface use NSData (byte[]) as a parameter or return value?

Edit: As per the answer below, the answer is YES, it can
I tried looking through the docs but didn't find any reference to this
I tried building but there always is an error whenever the return value or a param in a native interface is NSData (byte[])
Is it not supported? Thx
For example, the following interfaces blow:
- (NSData*)someMethod{
}
- (void)someMethod:(NSData*)param{
}
The server error file never mentions any specific error when an error occurs in a native interface class so I am asking here for clarity/reference
I'm not sure about the return value but the parameter should work and is documented in Listing 22. NativeInterface definition in the developer guide as:
public void test(byte b, boolean boo, char c, short s,
int i, long l, float f, double d, String ss,
byte[] ba, boolean[] booa, char[] ca, short[] sa, int[] ia,
long[] la, float[] fa, double[] da,
PeerComponent cmp);
Which generates:
-(void)test:(char)param param1:(BOOL)param1
param2:(int)param2 param3:(short)param3 param4:(int)param4
param5:(long long)param5 param6:(float)param6
param7:(double)param7 param8:(NSString*)param8
param9:(NSData*)param9 param10:(NSData*)param10
param11:(NSData*)param11 param12:(NSData*)param12
param13:(NSData*)param13 param14:(NSData*)param14
param15:(NSData*)param15 param16:(NSData*)param16
param17:(void*)param17;
}
If you're getting an error we'll need the link for the full error log as well as the applicable native interface code.

Creating topic in publisher (ZeroMQ)

I've been writing code for a PUB-SUB ZeroMQ system (in C), with one publisher and multiple subscribers.
On the client code, I must subscribe to a topic, according to a filter, like so:
(...)
void *context = zmq_ctx_new ();
void *subscriber = zmq_socket (context, ZMQ_SUB);
int rc = zmq_connect (subscriber, "tcp://localhost:5555");
char *filter = (argc > 1)? argv [1]: "10001 "; // example of a filter
rc = zmq_setsockopt (subscriber, ZMQ_SUBSCRIBE, filter, strlen (filter));
(...)
However, looking at code examples of the publisher (seen in the documentation of ZeroMQ), I don't see any line where the topic is created:
(...)
void *context = zmq_ctx_new ();
void *publisher = zmq_socket (context, ZMQ_PUB);
int rc = zmq_bind (publisher, "tcp://*:5556");
while (1) {
(...)
char update [20];
sprintf (update, "%05d %d %d", zipcode, temperature, relhumidity);
s_send (publisher, update);
(...)
The message is simply sent and no topic is specified. How is this possible?
In python versions, I've seen, in the publisher code:
socket.send_string("%d %d" % (topic, number))
but I have not seen anything like this in C.
Publishers don't explicity set topics in ZMQ. Topics are implied by the message, starting from the first character. The python code example is just a simple string concatenation that adds the "topic" to the front of the message.
Say you publish a message:
Hello - I am a ZMQ message
subscribing to
H
Hello
Hello -
Will all receive your message.
Welcome to ZeroMQ Zen-of-Zero.
All bytes of the message are considered as The Topic and the subscriber-side specified "Topic-filtering" operates on trivial and plain byte-matching of the set of subscribed-to topics against the left-n-bytes of the message.
Those messages, that match any of the recorded Topic(s) are considered as messages to be delivered, those not matching any one are not ( except when an inverse matching option was set )

Why try ... except block is not working here

I am trying to run following code with try.. except block:
program TriangleArea;
uses crt, sysutils;
type
num = real;
var
a, b, c, s, area : num;
begin
write('Enter lengths of 3 sides (separated by spaces): ');
try
readln (a, b, c);
s := (a + b + c)/2.0;
area := sqrt(s * (s - a)*(s-b)*(s-c));
writeln(area);
except
on E: Exception do
ShowMessage( 'Error: '+ E.ClassName + #13#10 + E.Message );
end;
end.
But it is giving following error:
$ fpc triangle_area.pas
Free Pascal Compiler version 3.0.0+dfsg-11+deb9u1 [2017/06/10] for x86_64
Copyright (c) 1993-2015 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling triangle_area.pas
triangle_area.pas(14,2) Error: Identifier not found "try"
triangle_area.pas(15,3) Fatal: Syntax error, ";" expected but "identifier READLN" found
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
Why "try" identifier is not being found. I am using fpc version 3.0.0 on Debian stable Linux.
Where is the problem and how can it be solved? Thanks for your help.
Place {$MODE OBJFPC} or {$MODE DELPHI} beneath your program declaration.
The reason is that by default the compiler will compile in MODE FPC, which does not support exceptions.
Additional sources: One Two Three
On the other hand, the ShowMessage instruction will not compile with Free Pascal. The correct code is:
program TriangleArea;
{$mode delphi}
uses crt, sysutils;
type
num = real;
var
a, b, c, s, area : num;
begin
write('Enter lengths of 3 sides (separated by spaces): ');
try
readln (a, b, c);
s := (a + b + c)/2.0;
area := sqrt(s * (s - a)*(s-b)*(s-c));
writeln(area);
except
on E: Exception do
write( 'Error: '+ E.ClassName + #13#10 + E.Message );
end;
end.
Later edit: the declaration type num=real is correct, but I don't see any real use of it.

C: Making an equation appears only once

I have following C code. The statement calculating simple_root appears twice. I am wondering if there is a better way to organise the code making the statement appear only once.
If putting the simple_root after the last else, there is a risk of error, e.g. the previous two conditions doesn't match. Please correct me if I am wrong.
if(fabs(quartic_polynomial(a, b, c, d, e, secDerivRoot_1)) < 1e-6)
{
triple_root = secDerivRoot_1;
simple_root = -b/a - 3*triple_root;
}
else if (fabs(quartic_polynomial(a, b, c, d, e, secDerivRoot_2)) < 1e-6)
{
triple_root = secDerivRoot_2;
simple_root = -b/a - 3*triple_root;
}
else
printf("Something is wrong. No common root with its 2nd derivative. \n");
You are missing something in the comment
If putting the simple_root after the last else, there is a risk of error, e.g. the previous two conditions doesn't match
This is already the case - if you don't match those two then triple_root and simple_root are already not set. I'm not sure how they are used after this piece of code or what your error handling is. You can either return immediately after the printf statement or set triple_root to be a NaN.
Then you can move the simple_root equation below the if statement. Alternatively you could put that in to a function. A one line function is fine and can make the code easier to understand.
I think the following should do it. I haven't compiled it or tested it so you may need to tweak something.
However your original formulation is much more readable and I really see no advantage to doing it this way.
And with this approach you are always doing both of the quartic_polynomial() calls rather than sometimes only doing one which may be much worse computationally speaking so far as CPU usage and time than duplicating a line of code.
I am curious if the two if statements could both be true. What are you to do in a case like that or can you just choose which ever you like?
{
int sec_1 = (fabs(quartic_polynomial(a, b, c, d, e, secDerivRoot_1) < 1e-6);
int sec_2 = (fabs(quartic_polynomial(a, b, c, d, e, secDerivRoot_2) < 1e-6);
if (! (sec_1 || sec_2)) {
printf("Something is wrong. No common root with its 2nd derivative. \n");
} else {
if (sec_1)
triple_root = secDerivRoot_1;
else
triple_root = secDerivRoot_2;
simple_root = -b/a - 3*triple_root;
}
}
Another approach, if a desire to prevent one statement from being updated and the other not would be something like the following:
#define SIMPLE_ROOT_CALC simple_root = -b/a - 3*triple_root
if(fabs(quartic_polynomial(a, b, c, d, e, secDerivRoot_1)) < 1e-6)
{
triple_root = secDerivRoot_1;
SIMPLE_ROOT_CALC;
}
else if (fabs(quartic_polynomial(a, b, c, d, e, secDerivRoot_2)) < 1e-6)
{
triple_root = secDerivRoot_2;
SIMPLE_ROOT_CALC;
}
else
printf("Something is wrong. No common root with its 2nd derivative. \n");
or even something like:
#define ROOT_CALC(x) triple_root = (x); simple_root = -b/a - 3*triple_root;
if(fabs(quartic_polynomial(a, b, c, d, e, secDerivRoot_1)) < 1e-6)
{
ROOT_CALC(secDerivRoot_1);
}
else if (fabs(quartic_polynomial(a, b, c, d, e, secDerivRoot_2)) < 1e-6)
{
ROOT_CALC(secDerivRoot_2);
}
else
printf("Something is wrong. No common root with its 2nd derivative. \n");
or perhaps depend on evaluation short circuit with the logical Or operator:
{
double x;
if (! (((x = secDerivRoot_1), fabs(quartic_polynomial(a, b, c, d, e, secDerivRoot_1) < 1e-6)) || ((x = secDerivRoot_2), fabs(quartic_polynomial(a, b, c, d, e, secDerivRoot_2) < 1e-6) )) ) {
printf("Something is wrong. No common root with its 2nd derivative. \n");
} else {
triple_root = x;
simple_root = -b / a - 3 * triple_root;
}
}

How to signal an R exception from C code

The stop function in R can be called with a list object in order to signal an exception of a particular type. For example to signal a foo exception, we can do:
foo <- list (
message = "my foo error"
)
class(foo) <- c("foo", "condition")
tryCatch (
stop(foo),
foo = function(e){"never mind foo."}
)
Is there an interface for doing this (signaling custom exceptions) from C code? The Rf_error only allows for raising generic errors, it does not allow for specifying a exception class.
Based on the suggestions above I wrote this function that does what I need:
void signal_exception(const char* message, const char* condition){
//the condition object
SEXP vec = PROTECT(allocVector(VECSXP, 1));
SET_VECTOR_ELT(vec, 0, mkString(message));
setAttrib(vec, R_NamesSymbol, mkString("message"));
//the class vector
SEXP cls = PROTECT(allocVector(STRSXP, 3));
SET_STRING_ELT(cls, 0, mkChar(condition));
SET_STRING_ELT(cls, 1, mkChar("error"));
SET_STRING_ELT(cls, 2, mkChar("condition"));
setAttrib(vec, R_ClassSymbol, cls);
//signal the condition by calling base::stop
SEXP stop_sym = PROTECT(Rf_install("stop"));
SEXP call = PROTECT(Rf_lang2(stop_sym, vec));
UNPROTECT(4);
Rf_eval(call, R_GlobalEnv);
}
It basically generalizes Rf_error with a second argument that you can use to specify the class of the error.
I don't think it is very elegant to call base::stop from C, only to have it call back to .Internal(.signalCondition()) but I it looks like there is currently no API for signalling the condition directly from C.
A standard example of how to do it in C++ is in this Rcpp Gallery post.
Taking just the first part with one minor edit:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
double takeLog(double val) {
try {
if (val <= 0.0) { // log() not defined here
throw std::range_error("Inadmissible value");
}
return log(val);
} catch(std::exception &ex) {
forward_exception_to_r(ex);
} catch(...) {
stop("c++ exception (unknown reason)");
}
return NA_REAL; // not reached
}
works as expected:
R> sourceCpp("/tmp/ex.cpp")
R> takeLog(-1)
Error: Inadmissible value
R>
The remainder of that post has some details.

Resources