Lex : print line numbers - count

I have a source code and I would like to add line numbers.
What I've done :
%{
int lines=0;
%}
LINE \n
%%
{LINE} {ECHO;printf("%d", ++lines);}
However, I don't know how to catch the first line.
Can you help me ?

Add the line:
printf("%d", ++lines);
as the first thing in main. Its a hack, but an effective one :)
Edit: The result should look something like this:
%{
int lines=0;
%}
LINE \n
%%
{LINE} {ECHO;printf("%d", ++lines);}
%%
main()
{
printf("%d", ++lines);
yylex();
}
Disclaimer: syntax from a book, not actually compiled. You might have to massage it a little bit.

Try this:
%{
#include<stdio.h>
int lines=0;
%}
%%
.*\n {printf("%d %s",++lines,yytext);}
%%
int main()
{
yylex();
return 0;
}

%{
int yylineno=0;
%}
%%
^(.*)\n {printf("%4d %s",++yylineno,yytext);
%%
int main(int argc, char **argv)
{
yyin=fopen(argv[1],"r");
yylex();
fclose(yyin);
}

Check to see if your version provides a variable named "yylineno", many of them do.
I know flex 2.6.0 does.

Related

yylval undefined with lex and yacc

I was trying a simple program to create an abstract syntax tree using lex and yacc.
My yacc_file.y is
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
struct node *left;
struct node *right;
char *token;
} node;
node *mknode(node *left, node *right, char *token);
void printtree(node *tree);
#define YYSTYPE struct node *
%}
%start lines
%token NUMBER
%token PLUS MINUS TIMES
%token LEFT_PARENTHESIS RIGHT_PARENTHESIS
%token END
%left PLUS MINUS
%left TIMES
%%
lines: /* empty */
| lines line /* do nothing */
line: exp END { printtree($1); printf("\n");}
;
exp : term {$$ = $1;}
| exp PLUS term {$$ = mknode($1, $3, "+");}
| exp MINUS term {$$ = mknode($1, $3, "-");}
;
term : factor {$$ = $1;}
| term TIMES factor {$$ = mknode($1, $3, "*");}
;
factor : NUMBER {$$ = mknode(0,0,(char *)yylval);}
| LEFT_PARENTHESIS exp RIGHT_PARENTHESIS {$$ = $2;}
;
%%
int main (void) {return yyparse ( );}
node *mknode(node *left, node *right, char *token)
{
/* malloc the node */
node *newnode = (node *)malloc(sizeof(node));
char *newstr = (char *)malloc(strlen(token)+1);
strcpy(newstr, token);
newnode->left = left;
newnode->right = right;
newnode->token = newstr;
return(newnode);
}
void printtree(node *tree)
{
int i;
if (tree->left || tree->right)
printf("(");
printf(" %s ", tree->token);
if (tree->left)
printtree(tree->left);
if (tree->right)
printtree(tree->right);
if (tree->left || tree->right)
printf(")");
}
int yyerror (char *s) {fprintf (stderr, "%s\n", s);}
My lex_file.l file is
%{
#include "yacc_file.tab.h"
%}
%%
[0-9]+ {yylval = (int)yytext; return NUMBER;}
/* cast pointer to int for compiler warning */
[ \t\n] ;
"+" return(PLUS);
"-" return(MINUS);
"*" return(TIMES);
"(" return(LEFT_PARENTHESIS);
")" return(RIGHT_PARENTHESIS);
";" return(END);
%%
int yywrap (void) {return 1;}
To run, I have done the following
yacc -d yacc_file.y
lex lex_file.y
cc y.tab.c lex.yy.c -o a.exe
I got the following error
lexfile.l: In function 'yylex':
lex_file.l:10:2: error: 'yylval' undeclared(first used in this function)
[0-9]+ {yylval=(int)yytext; return NUMBER;}
I have searched on google and %union seems to solve the problem. But I am not sure how to use it.
The command
yacc -d yacc_file.y
produces a header file called y.tab.h and a C file called y.tab.c. That's the yacc-compatible default naming, and it does not agree with your flex file, which is expecting the header to be called yacc_file.tab.h.
You could just change the #include statement in your flex file, but that wouldn't be compatible with the build system at your college. So I suggest you change to the command bison -d yacc_file.y instead of your yacc command. That will produce a header file called yacc_file.tab.h and a C file called yacc_file.tab.c. (Of course, you will then have to change the cc command to compile yacc_file.tab.c instead of y.tab.c.)
Presumably there is some incorrect yacc_file.tab.h on your machine, which doesn't include a declaration of yylval. Hence the compilation error.
To avoid confusing yourself further, when you fix your build procedure I'd recommend deleting all the intermediate files -- y.tab.h and y.tab.c as well as yacc_file.tab.c and yacc_file.tab.h, and lex.yy.c. Then you can do a clean build without having to worry about picking up some outdated intermediate file.
Also, in yacc_file.y, you #define YYSTYPE as struct node *. That's fine, but the #define will not be copied into the generated header file; in the header file, YYSTYPE will be #defined as int if there is no other #define before the header file is #included.
Moreover, in lex_file.l you use yylval as though it were an int (yylval = (int)yytext;) but I think that statement does not do what you think it does. What it does is reinterpret the address of yytext as an integer. That's legal but meaningless. What you wanted to do, I think, is to convert the string in yytext as an integer. To do that, you need to use strtod or some similar function from the standard C library.
Regardless, it is vital that the scanner and the parser agree on the type of yylval. Otherwise, things will go desperately wrong.
As you mention, it is possible to use a %union declaration to declare YYSTYPE as a union type. You should make sure you understand C union types, and also read the bison manual section on semantics..

Looking for a script or something to generate the numbers 1.1.1.1 to 255.255.255.255

Yes thats right, I am looking for a script or anything that can generate an ip address
list from 1.1.1.1 to 255.255.255.255. Even if its something like cat or grep that generates
the numbers 1.1.1.1 to 255.255.255.255. Thanks!
I found 1 python script but it seems to not work very well.
A simple C program:
#include <stdio.h>
#include <limits.h>
#if UINT_MAX != 4294967295
#error Assumes 32-bit ints for stopping condition.
#endif
int main() {
unsigned n = 0x01010101;
for ( ; n != 0; ++n)
printf("%d.%d.%d.%d\n", n>>24, (n>>16)&0xff, (n>>8)&0xff, n&0xff);
return 0;
}
Just redirect standard output to a file and leave it running for ... I don't know how long.
I'm assuming you're looking for a string format?
int a,b,c,d;
char address[16];
char e[4],f[4],g[4],h[4];
for(a=1;a<=255;a++)
{
for(b=1;b<=255;b++)
{
for(c=1;c<=255;c++)
{
for(d=1;d<=255;d++)
{
//You'll want to clear e,f,g, and h here, as well as null-terminating
//them once they've been cast and copied.
strcpy(e,((char)(a)));//Cast your rolling 'int's to 'char's
strcpy(f,((char)(b)));
strcpy(g,((char)(c)));
strcpy(h,((char)(d)));
strcpy(address,"\0");//Clear your string before constructing
strcat(address,e);
strcat(address,'.');//Might need double-quotes(".")
strcat(address,f);
strcat(address,'.');
strcat(address,g);
strcat(address,'.');
strcat(address,h);
strcat(address,'\0');
//Do whatever you need to do here. (Copy to array or whatever)
}
}
}
}

How to deal with "%1" in the argument of QString::arg()?

Everybody loves
QString("Put something here %1 and here %2")
.arg(replacement1)
.arg(replacement2);
but things get itchy as soon as you have the faintest chance that replacement1 actually contains %1 or even %2 anywhere. Then, the second QString::arg() will replace only the re-introduced %1 or both %2 occurrences. Anyway, you won't get the literal "%1" that you probably intended.
Is there any standard trick to overcome this?
If you need an example to play with, take this
#include <QCoreApplication>
#include <QDebug>
int main()
{
qDebug() << QString("%1-%2").arg("%1").arg("foo");
return 0;
}
This will output
"foo-%2"
instead of
"%1-foo"
as might be expected (not).
qDebug() << QString("%1-%2").arg("%2").arg("foo");
gives
"foo-foo"
and
qDebug() << QString("%1-%2").arg("%3").arg("foo");
gives
"%3-foo"
See the Qt docs about QString::arg():
QString str;
str = "%1 %2";
str.arg("%1f", "Hello"); // returns "%1f Hello"
Note that the arg() overload for multiple arguments only takes QString. In case not all the arguments are QStrings, you could change the order of the placeholders in the format string:
QString("1%1 2%2 3%3 4%4").arg(int1).arg(string2).arg(string3).arg(int4);
becomes
QString("1%1 2%3 3%4 4%2").arg(int1).arg(int4).arg(string2, string3);
That way, everything that is not a string is replaced first, and then all the strings are replaced at the same time.
You should try using
QString("%1-%2").arg("%2","foo");

How can I get the current mouse (pointer) position co-ordinates in X

This can either be some sample C code or a utility that will show me either gui or on the console it doesn't matter, but I have to be able to "command" it to grab the co-ordinates at an exact time which makes xev not very useful (that I could figure out).
I'm not a C programmer by any means but I looked at a couple of online tutorials and think this is how you are supposed to read the current mouse position. This is my own code and I'd done nothing with Xlib before so it could be completely broken (for example, the error handler shouldn't just do nothing for every error) but it works. So here is another solution:
#include <X11/Xlib.h>
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
#include <malloc.h>
static int _XlibErrorHandler(Display *display, XErrorEvent *event) {
fprintf(stderr, "An error occured detecting the mouse position\n");
return True;
}
int main(void) {
int number_of_screens;
int i;
Bool result;
Window *root_windows;
Window window_returned;
int root_x, root_y;
int win_x, win_y;
unsigned int mask_return;
Display *display = XOpenDisplay(NULL);
assert(display);
XSetErrorHandler(_XlibErrorHandler);
number_of_screens = XScreenCount(display);
fprintf(stderr, "There are %d screens available in this X session\n", number_of_screens);
root_windows = malloc(sizeof(Window) * number_of_screens);
for (i = 0; i < number_of_screens; i++) {
root_windows[i] = XRootWindow(display, i);
}
for (i = 0; i < number_of_screens; i++) {
result = XQueryPointer(display, root_windows[i], &window_returned,
&window_returned, &root_x, &root_y, &win_x, &win_y,
&mask_return);
if (result == True) {
break;
}
}
if (result != True) {
fprintf(stderr, "No mouse found.\n");
return -1;
}
printf("Mouse is at (%d,%d)\n", root_x, root_y);
free(root_windows);
XCloseDisplay(display);
return 0;
}
xdotool might be the best tool for this.
For C, you can use libxdo.
Actually, xev is very useful if you supply it with the window id grabbed using xwininfo, then it can easily perform this task for you. There are no doubt much more elegant solutions but it works.
xinput can be used to print the full device state of any input device.
First you need to discover your device id:
$ xinput --list | grep -i mouse
⎜ ↳ Logitech USB Receiver Mouse id=11 [slave pointer (2)]
then you can ask for state:
$ xinput --query-state 11;
2 classes :
ButtonClass
button[1]=up
button[2]=up
button[3]=up
button[4]=up
button[5]=up
button[6]=up
button[7]=up
button[8]=up
button[9]=up
button[10]=up
button[11]=up
button[12]=up
button[13]=up
button[14]=up
button[15]=up
button[16]=up
button[17]=up
button[18]=up
button[19]=up
button[20]=up
ValuatorClass Mode=Relative Proximity=In
valuator[0]=274
valuator[1]=886
valuator[2]=0
valuator[3]=675
Or just a loop:
while sleep .2; do xinput --query-state $(xinput --list | grep -i mouse | cut -d= -f2 | cut -f1| head -1); done

How to capture output of execvp

I'm developing a program which executes a program using execvp. It needs to capture the results of the child process and parse them in the main process. It seems there is a way, using named pipes, and duping. I'm trying to hunt down a good example of this, but so far no luck. If anyone has any pointers, links and/or suggestions about this, I'd greatly appreciate it.
You don't need named pipes; unnamed pipes work just fine. Actually, often you can just use popen instead of doing the pipe/fork/dup/exec yourself. popen works like this (though your libc's implementation likely has more error checking):
FILE *popen(const char *command, const char *type) {
int fds[2];
const char *argv[4] = {"/bin/sh", "-c", command};
pipe(fds);
if (fork() == 0) {
close(fds[0]);
dup2(type[0] == 'r' ? 0 : 1, fds[1]);
close(fds[1]);
execvp(argv[0], argv);
exit(-1);
}
close(fds[1]);
return fdopen(fds[0], type);
}
This creates an unnamed pipe, and forks. In the child, it reattaches stdout (or stdin) to one end of the pipe, then execs the child. The parent can simply read (or write) from the other end of the pipe.
Can't you just use popen()?
Here is a simple example that demonstrates the use of popen to achieve your goal. Just put something more interesting than "echo" as the command :)
#include <stdio.h>
int main()
{
char buf[100];
int i = 0;
FILE *p = popen("echo \"Test\"","r");
if (p != NULL )
{
while (!feof(p) && (i < 99) )
{
fread(&buf[i++],1,1,p);
}
buf[i] = 0;
printf("%s",buf);
pclose(p);
return 0;
}
else
{
return -1;
}
}

Resources