[comp.lang.c] Question about Lex

gtir5@fel.tno.nl (Ger Timmens) (05/29/91)

This is what I do:

1. lex lexcommands         /* ==> lex.yy.c */
2. cc lex.yy.c             /* ==> a.out    */
3. a.out < input > output  /* ==> output   */

I've got the following problem:
When I encounter a string in the file *input* I want to
generate an error message reporting the line number and
file.
However I cannot include the following in my *lexcommands* file:

"string"       fprintf(stderr,"Found *string* on line %d in %s.\n",
                       __LINE__,__FILE__);

since this would report the line number in the file *lex.yy.c* !

Is there a solution to this problem ?
I've experimented with #line, but I did not succeed.

Thanks in advance,

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=     Ger Timmens,  Fysisch Elektronisch Laboratorium TNO     =
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=   Tel.:  070-3264221 tst. 308    @-mail: gtir5@fel.tno.nl   =
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
= >>> Any You Can Do, I Can Do Better, (No You Can't) ... <<< =
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

simonp@fulcrum.bt.co.uk (Simon Parsons) (05/30/91)

In article <1991May29.081912.16808@fel.tno.nl> gtir5@fel.tno.nl (Ger Timmens) writes:

   Path: uzi-9mm.fulcrum.bt.co.uk!axion!ukc!mcsun!hp4nl!tnofel!felfs!gtir5
   From: gtir5@fel.tno.nl (Ger Timmens)
   Newsgroups: comp.lang.c
   Date: 29 May 91 08:19:12 GMT
   Organization: TNO Physics and Electronics Laboratory
   Lines: 29

>   This is what I do:
>
>   1. lex lexcommands         /* ==> lex.yy.c */
>   2. cc lex.yy.c             /* ==> a.out    */
>   3. a.out < input > output  /* ==> output   */
>
>   I've got the following problem:
>   When I encounter a string in the file *input* I want to
>   generate an error message reporting the line number and
>   file.
>   However I cannot include the following in my *lexcommands* file:
>
>   "string"       fprintf(stderr,"Found *string* on line %d in %s.\n",
>			  __LINE__,__FILE__);
>
>   since this would report the line number in the file *lex.yy.c* !
>
>   Is there a solution to this problem ?
>   I've experimented with #line, but I did not succeed.

Within your lex script have a local line number counter,
and have a rule or part of a rule.

"\n"    { LineNo++; }

Therefore LineNo will always be correct.

Simon
--
        "Hey girl, as I've always said, I prefer your lips red, 
         Not what the good lord made, but what he intended."
                                                         
      Simon Parsons, Fulcrum Communications Ltd.- simonp@fulcrum.bt.co.uk

gtir5@fel.tno.nl (Ger Timmens) (05/31/91)

gtir5@fel.tno.nl (Ger Timmens) writes:

>This is what I do:

>1. lex lexcommands         /* ==> lex.yy.c */
>2. cc lex.yy.c             /* ==> a.out    */
>3. a.out < input > output  /* ==> output   */

>I've got the following problem:
>When I encounter a string in the file *input* I want to
>generate an error message reporting the line number and
>file.

[deleted text]

Here are the solutions:

The line number: use yylineno (a global Lex integer).

The file name:   instead of redirecting the input and output,
		 you use fixed file names. So

      3. a.out < input > output
becomes
      3. a.out input output
And you connect Lex's stdin and stdout (yyin and yyout) to these files:
So you get the following Lex file: (Thanks to you all) !!!!

-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

%{
	char	InFile[20];
	char	OutFile[20];
%}

%%
"string"	fprintf(stderr,"Found %s at line %d in file %s\n",
			yytext,yylineno,InFile);
%%


void main(int argc, char **argv)
{
	if (argc != 3)
	{
		fprintf(stderr,"Usage: %s <input-file>", argv[0]);
		fprintf(stderr," <ouput-file>\n");
		exit(1);
	}

	strcpy(InFile, argv[1]);
	strcpy(OutFile, argv[2]);
	yyin = fopen(InFile, "r");
	yyout = fopen(OutFile, "w");
	yylex();
	fclose(yyin);
	fclose(yyout);
}

martin@mwtech.UUCP (Martin Weitzel) (05/31/91)

In article <1991May29.081912.16808@fel.tno.nl> gtir5@fel.tno.nl (Ger Timmens) writes:
>This is what I do:
>
>1. lex lexcommands         /* ==> lex.yy.c */
>2. cc lex.yy.c             /* ==> a.out    */
>3. a.out < input > output  /* ==> output   */
>
>I've got the following problem:
>When I encounter a string in the file *input* I want to
>generate an error message reporting the line number and
>file.
>However I cannot include the following in my *lexcommands* file:
>
>"string"       fprintf(stderr,"Found *string* on line %d in %s.\n",
>                       __LINE__,__FILE__);
>
>since this would report the line number in the file *lex.yy.c* !

It's the purpose of the macros __LINE__ and __FILE__ to point you to the
source line - they don't have a meaning wrt the lines read at runtime.

If you have a 'plain vanilla' lex (as delivered with many UNIXes), there
might be an easy - yet undocumented - way: The standard input/unput-macros
support a variable 'yylino' which is incremented with every line read.

Of course, you can also build such a feature yourself by simply writing
a rule which recognices '\n' in the input and increments an arbitrary
variable.

>Is there a solution to this problem ?

Hope this helps.

>I've experimented with #line, but I did not succeed.

Also #line is not what you probably assume. It is meant to be used in
conjunction with __LINE__ and __FILE__ if your C source is generated from
some higher lever description. In this case #line sets the value of
__LINE__ and __FILE__ to point errors to the 'original' (higher level)
description.
-- 
Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83

simonp@fulcrum.bt.co.uk (Simon Parsons) (06/03/91)

In article <1159@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes:

>   If you have a 'plain vanilla' lex (as delivered with many UNIXes), there
>   might be an easy - yet undocumented - way: The standard input/unput-macros
>   support a variable 'yylino' which is incremented with every line read.

But if you want it to be 'portable' between lex and flex, you CAN define
a rule

"\n"   { LineNo++; }

and do it yourself.

Simon
--
        "Hey girl, as I've always said, I prefer your lips red, 
         Not what the good lord made, but what he intended."
                                                         
      Simon Parsons, Fulcrum Communications Ltd.- simonp@fulcrum.bt.co.uk