help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: how to work with Bison locations?


From: Luca
Subject: Re: how to work with Bison locations?
Date: Wed, 03 Jun 2009 07:28:43 +0200
User-agent: Thunderbird 2.0.0.21 (Windows/20090302)

Location are created by lexer and "reduced" by the parser, so you have to create them using the lexer:

#define YY_USER_ACTION {yylloc.first_line = yylineno; yylloc.first_column = colnum; colnum=colnum+yyleng; yylloc.last_column=colnum; yylloc.last_line = yylineno;}

this macro is executed at each token recognized by lex. Insert it in bug.l inside %{}%; you have to define and manage colnum, yylineno is automatically defined by flex. You can access to location using @ from parser actions, or using yylloc from flex.


You can also redefine, if you need, YYLTYPE (user custom locations, for example to add a field to the struct to track also file location), YYLLOC_DEFAULT (to merge locations) and YY_LOCATION_PRINT (to print locations) without any trouble. You have to redefine those macro BEFORE to include y.tab.h otherwise the compiler will complain.

Luca

Kynn Jones ha scritto:
Hi.  I'm working with Bison (and Flex) for the first time, and it's rough going.

I can't get Bison locations to work.  The following toy parser
illustrates the problem.

Here's the file for Flex, bug.l:

-------------------------------------------------------------------------------

%{
#include "bug.tab.h"
%}

%option noyywrap nounput outfile="bug.yy.c" header-file="bug.yy.h"

%%
   /* skip over whitespace */
[ \t\r\n]+

   /* bomb anywhere else */
<*>.                            { return TINVALID; }

%%

-------------------------------------------------------------------------------

Here's the file for Bison, bug.y:

-------------------------------------------------------------------------------

%{
#include "bug.tab.h"
#include "bug.yy.h"

void yyerror ( char const *s ) {}
%}

%defines
%token TINVALID

%%

bug: error {
              fprintf( stderr,
                       "@$: %d:%d-%d:%d\n",
                       @$.first_line,
                       @$.first_column,
                       @$.last_line,
                       @$.last_column );
              return -1;
            }
    ;
%%

-------------------------------------------------------------------------------


Here's the file parsebug.c:

-------------------------------------------------------------------------------
#include <stdio.h>
#include "bug.tab.h"
#include "bug.yy.h"

extern int yyparse();

int main (int argc, char **argv) {

  yyout = fopen( "/dev/null", "w" );
  yyin = argc > 1 ? fopen( argv[ 1 ], "r" ) : stdin;

  return yyparse();
}
-------------------------------------------------------------------------------



Here's what I run:

% bison bug.y
% flex bug.l
% gcc -Wall --pedantic bug.tab.c bug.yy.c parsebug.c -o bug
% ( echo "\n\nfoo\n\n" | bug ) || echo "exited with error"
@$: 1:1-1:1
exited with error


So the parser fails, as expected, but no matter what the input is, the
first line of the output is always "@$: 1:1-1:1\n".  This makes no
sense to me.  If the "location" is going to be of any use, I'd expect
that it would reflect the position in the input where the parser
and/or scanner first got stuck.  I.e. I expect that, with the input
above, at least one of the fields in @$ would be greater than 1.

Am I misunderstanding the meaning of Bisons "locations"?  If not, what
am I doing wrong?

BTW, what's the standard way of implementing the handling of a
"scanner error" condition (i.e. to cover cases when the scanner finds
something that it does not expect).

Thanks!

kynn


_______________________________________________
address@hidden http://lists.gnu.org/mailman/listinfo/help-bison






reply via email to

[Prev in Thread] Current Thread [Next in Thread]