Where's the syntax error in this (f)lex snippet? - lex

I'm having a great time doing a lexer using flex. Problem is, my code editor doesn't color the syntax of the file, and it seems my rule has an error in it. Since I'm not too sure about how to use single quotes and double quotes inside intervals, I thought I'd share that snippet with you:
[^\\\'\n]+
{
wchar_t* string;
utf8_decode(yytext, &string);
yyextra->append(string);
free(string);
}
Flex tells me there's an 'unrecognized rule' on the utf8_decode line. If I remove the whole rule, things look fine again.
Can anyone tell what I'm doing wrong here?

The action must begin on the same line as the pattern. So use
[^\\\'\n]+ {
wchar_t* string;
utf8_decode(yytext, &string);
yyextra->append(string);
free(string);
}

Related

Matlab unable to format string to path

In original script there is part of code where is this
filepathsource='C:\Users\...';
strFP=dir([filepathsource '*.txt']);
Which works nicely.
Problem is that i need to change that filepathsource to some more dynamic so i did.
filepathsource=string(strcat(app.folderPath,'\',string(app.currentCount),'\'));
strFP=dir([filepathsource '*.txt']);
But i end with error
Error using dir
Name must be a text scalar.
And i need original formating because i get errors later in script. Is there any way how can i fix it? I tried everything but always is something somewhere wrong. And i just dont understand whats difference between original filepathsource and the one that i created bot are strings. (output of my filepathsource is correct when i display it)

Latex - Why comments environments do not work in macros?

I'm trying to crate a macro that could display different levels of details in a Resume, the idea being to be able to state a specific theme and to get details only for relevant entries in my resume.
I'm using class "memoir" to use the \newcomment function. I tried moderncv, but I was not really convinced.
Here is what I've come up with so far :
\newcomment{Item}
\newcomment{Descr}
\newcomment{Details}
\newcommand{\cvitem}[3]{
\begin{Item}\textbf{#1}\end{Item}
\begin{Descr}\hspace{1cm} {#2}\end{Descr}
\begin{Details}\\ {\small #3}\end{Details}\vspace{2em}
}
\commentsoff{Item}
\commentsoff{Descr}
\commentsoff{Details}
It works as is, but if I state
\commentson{Details}
Then I get the error :
! File ended while scanning use of \next.
<inserted text>
\par
<*> cv_master.tex
I suspect you have forgotten a `}', causing me
to read past where you wanted me to stop.
I'll try to recover; but if the error is serious,
you'd better type `E' or `X' now and fix your file.
Any idea why ?
You're better of using conditionals in the traditional sense. That is, use \if-like statements that you can toggle on/off:
\documentclass{article}
\newif\ifItem
\newif\ifDescr
\newif\ifDetails
\newcommand{\cvitem}[3]{%
\ifItem
\textbf{#1}
\fi
\ifDescr
\hspace{1cm} #2
\fi
\ifDetails
\\ {\small #3}
\fi
\vspace{2em}
}
\Itemtrue
\Descrtrue
\Detailsfalse
\begin{document}
\cvitem{First}{Second}{Third}
\end{document}
Why? It's easier and works in all environments/classes.

Exim getting random credential in exim.conf

I have been trying to get perl subroutine value and substitution to get the required part of string from randomips subroutine in exim.conf. However when i use string substitution i get error as follow:
Here is what I am trying to achieve
I am trying to split string by colon and get first occurrence as "interface". I'll be using second occurrence as the "helo_data.
exim.pl
sub randomhosts {
#inet = ("x.x.x.1:hostname1.domain.com","x.x.x.2:hostname2.domain.com","x.x.x.3:hostname3.domain.com"
);
return $inet[int rand($#inet+1)];
}
exim.conf
dkim_remote_smtp:
driver = smtp
interface = "${perl{randomhosts}%:*}"
helo_data = "${sender_address_domain}"
Error I get is as follow:
"failed to expand "interface" option for dkim_remote_smtp transport: missing '}' after 'perl'".
Probably the syntax.
Any help?
The code that you are trying to copy was written by someone who doesn't know much about Perl. It includes this line:
return $inet[int rand($#inet+1)];
A Perl programmer would write this as
return $inet[rand #inet];
I think there are a couple of issues here - one with your Exim syntax and one with your Perl syntax.
Exim is giving you this error:
failed to expand "interface" option for dkim_remote_smtp transport: missing '}' after 'perl'
I don't know anything about calling Perl from Exim, but this page mentions a syntax like ${perl{foo}} (which is similar to the one used in the page you are copying from) and one like ${perl{foo}{argument}} for calling a subroutine and passing it an argument. Nowhere does it mention syntax like yours:
${perl{randomhosts}%:*}
I'm not sure where you have got that syntax from, but it seems likely that this is what is causing your first error.
In a comment, you say
I am stying to get first part of string before colon for each random array value for "interface" and part after colon for "helo_data"
It seems to me that Exim doesn't support this requirement. You would need to call the function twice to get the two pieces of information that you require. You might be able to do this in the Perl using something like state variables - but it would be far more complex than the code you currently have there.
Secondly, your Perl code has a syntax error, so even if Exim was able to call your code, it wouldn't work.
The code you're copying sets up #inet like this:
#inet = ("x.x.x.1", "x.x.x.2", "x.x.x.3", "x.x.x.4");
Your equivalent code is this:
#inet = (
"x.x.x.1:hostname1.domain.com",
"x.x.x.2:hostname2.domain.com,
x.x.x.3:hostname3.domain.com
);
I've reformatted it, to make the problems more obvious. You are missing a number of quote marks around the elements of the array. (Note: I see that while I have been writing this answer, you have fixed that.)
Update: Ok, here is some code to put into exim.pl that does what you want.
use feature qw[state];
sub randomhosts {
state $current;
my #inet = (
"x.x.x.1:hostname1.domain.com",
"x.x.x.2:hostname2.domain.com",
"x.x.x.3:hostname3.domain.com"
);
if ($_[0] eq 'generate') {
shift;
#{$current}{qw[ip host]} = split /:/, $inet[rand #inet];
}
return $current->{$_[0]};
}
It generates a new ip/host pair if its first argument is 'generate'. It will then return either the hostname or the ip address from the generated pair. I think you can probably call it from your Exim config file like this:
dkim_remote_smtp:
driver = smtp
interface = "${perl{randomhosts}{generate}{ip}}"
helo_data = "${perl{randomhosts}{host}}"
But I'm no expert in Exim, so that syntax might need tweaking.
First I would like to note I have not worked with exim so I cannot say what exactly you are trying to do and why you have done things exactly so.
In the link you posted, a method called 'randinet' is added to exim.pl and the interface line in exim.conf is replaced by
interface = "${perl{randinet}}"
You have implemented a 'randomhosts' method and replaced the interface line with
interface = "${perl{randomhosts}%:*}"
Now the parser complains about not finding the closing bracket. That is likely due to the symbols you felt free to add but the parser does not have the freedom to ignore.
I suggest you try
interface = "${perl{randomhosts}}"

Create annotation using regexp on document text

I am trying to annotate a json document using regular expression. I can create a simple annotation to mark a "JsonBlock" using the following, but, I cannot seem to turn around and use that annotaiton "JsonBlock" in a loop.
My document looks something like this:
{ "Key": { "JsonBlock": { [
{"id":"123","value":"This is some multi-line long text..." },
{"id":"456","value":"This is some multi-line long text..." } ] } } }
Here is a simple regex based expression that creates an annotaiton
("([{\\s\"]*id.*?\\})")-> JsonBlock;
But, why can't I iterate over JsonBlock annotations using the following? I should be missing something!
BLOCK(myBlock)JsonBlock{}{
}
Beyond that too, I have another annotation that represents the id as "JsonBlockId", I have tried to use PARTOF to check if the JsonBlockId is part of JsonBlock and that rule does not seem to fire. I should be missing something.
Any pointers would be appreciated.
Thanks!
The BLOCk does not match because the JsonBlock annotations are visible.
Please mind that all annotations are invisible if their begin offset or end offset is covered by any invisible annotation. In you example, this is BREAK and/or SPACE.
You can fix the problem by either changing your regex not to include the whitespaces, or you can make whitespace visible, or you can change the offsets of the annotations not to include the whitespaces. Here are the latter two options:
DECLARE JsonBlock;
"([{\\s\"]*id.*?\\})"-> JsonBlock;
RETAINTYPE(WS);
BLOCK(first) JsonBlock{}{
}
RETAINTYPE;
RETAINTYPE(WS);
JsonBlock{-> TRIM(WS)};
RETAINTYPE;
BLOCK(first) JsonBlock{}{
}
Your example rule was not valid. I removed the brackets.
DICLAIMER: I am a developer of UIMA Ruta

SSIS Formatting input from flat file

I'm a SSIS newbie. I wanna format the inputs of my flat file before saving the entries in a database table. Initially I created a flat file as follows:-
"1","Superman","Metropolis"
"2","Batman","Gotham"
"3","Spiderman","New York"
"4","James Bond","London"
"5","Green Lantern","Oa"
The solution for stripping this was simple as shown here http://www.mssqltips.com/sqlservertip/1316/strip-double-quotes-from-an-import-file-in-integration-services-ssis/
But now i have created a new similar package and given my input file like this:-
"6", "TMNT", "Sewers NY"
"7", "Iron Man", "New York"
Note here I've put a space after the delimiting comma. Now when I follow the above method the first number field stripped of the double quotes, but rest of the entries retain their quotes. Any idea how to work around this? One suggestion on a similar question on stackoverflow mentioned use of a "Transformation script". Since I'm a newbie can anyone please throw light on this method?
Yes, you can use Script component transformation. Select all columns, and change them to ReadWrite. The code:
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
Row.ID = Row.ID.Replace("\"", string.Empty);
Row.Movie = Row.Movie.Replace("\"", string.Empty);
Row.City = Row.City.Replace("\"", string.Empty);
}
If you want to trim the spaces you can use
Row.ID.Replace("\"", string.Empty).Trim();
You would also need to take care if you want to preserve the values that are " ". Please post if the suggestion was helpful or if you have any questions.
In the 'General' tab you can set a text qualifier of ". Then those quotes will be ignored.
Then you don't need to write error prone script when there is a simple solution.