help-flex
[Top][All Lists]
Advanced

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

Re: why are locations dictated by bison?


From: Akim Demaille
Subject: Re: why are locations dictated by bison?
Date: 12 Jan 2002 13:36:30 +0100
User-agent: Gnus/5.0808 (Gnus v5.8.8) XEmacs/21.4 (Common Lisp)

>>>>> "Akim" == Akim Demaille <address@hidden> writes:

Akim> The real issue is (2), indeed.  Please see my post were I
Akim> explained the two levels of help you could provide.  Or better:
Akim> show me a Flex file showing the interface we have in mind.  We
Akim> don't seem to understand each other because we don't have code
Akim> to comment.  I'm not asking for an implementation, just a
Akim> theoretic foo.l.  _Then_ it will be easier to discuss.

I suggest that you show me how you can simplify the following location
tracking scanner, so that we can really compare the two methods.

Oh, watch out: here I use a C++ class to compute locations.  One
location is composed of two Positions.  Of course, Flex must let me do
that, just like Bison let's me use a C++ class here.

%{                                                            /* -*- C -*- */

#include <string>
#include <errno.h>
#include "common.hh"
#include "parse/parse.hh"

#include "absyn/all.hh"
using namespace absyn;

#include "parse/parsetiger.h"

#define YY_NEVER_INTERACTIVE 1

static int comment_level = 0;
static std::string current_file;

#define YY_USER_INIT                            \
  do {                                          \
    yylloc->begin.filename = current_file;      \
    yylloc->end.filename = current_file;        \
  } while (0)

#define YY_USER_ACTION                          \
    yylloc->column (yyleng);


/* End the marking here. */

//<<
%}

%option noyywrap
%option nounput

%x STATE_COMMENT STATE_STRING

id      [a-zA-Z][a-zA-Z_0-9]*
int     [0-9]+
eol     \n|\r|\n\r|\r\n

%%

%{
  yylloc->step ();
%}

[ \t]+      yylloc->step ();
{eol}       yylloc->line (yyleng); yylloc->step ();
"/*"        comment_level++; BEGIN STATE_COMMENT;
","         return COMMA;
":"         return COLON;
";"         return SEMI;
"("         return LPAREN;
")"         return RPAREN;
"["         return LBRACK;
"]"         return RBRACK;
"{"         return LBRACE;
"}"         return RBRACE;
"."         return DOT;
"+"         return PLUS;
"-"         return MINUS;
"*"         return TIMES;
"/"         return DIVIDE;
"="         return EQ;
"<>"        return NE;
"<"         return LT;
"<="        return LE;
">"         return GT;
">="        return GE;
"&"         return AND;
"|"         return OR;
":="        return ASSIGN;
"array"     return ARRAY;
"if"        return IF;
"then"      return THEN;
"else"      return ELSE;
"while"     return WHILE;
"for"       return FOR;
"to"        return TO;
"do"        return DO;
"let"       return LET;
"in"        return IN;
"end"       return END;
"of"        return OF;
"break"     return BREAK;
"nil"       return NIL;
"function"  return FUNCTION;
"var"       return VAR;
"type"      return TYPE;
{int}       yylval->ival = atoi (yytext); return INT;
{id}        {
              yylval->symbol = new symbol::Symbol (yytext) ;
              return ID;
             }
\"          yylval->str = new std::string (); BEGIN STATE_STRING;
.           {
  yylloc->word (yyleng);
  std::cerr << *yylloc << ": invalid character: `"
            << *yytext << "'" << std::endl;
  if (!exit_status)
    exit_status = exit_scan;
  }

<STATE_COMMENT>{ /* Comments. */
  "*/" { /* End of the comment. */
    if (--comment_level == 0)
      {
        yylloc->step ();
        BEGIN INITIAL;
      }
  }

  "/*"          comment_level++;
  [^*/\n\r]+    ;
  {eol}+        yylloc->line (yyleng);
  .             /* Stray `*' and `/'. */;

  <<EOF>> {
    std::cerr
      << *yylloc << ": unexpected end of file in a comment" << std::endl;
    if (!exit_status)
      exit_status = exit_scan;
    BEGIN INITIAL;
  }
}

<STATE_STRING>{ /* Handling of the strings.  Initial " is eaten. */
     \" {
       BEGIN INITIAL;
       return STRING;
     }

     \\[0-7]{3}         {
       long c = strtol (yytext + 1, 0, 8);
       if (c > 255)
         {
           std::cerr << *yylloc << ": invalid escape: " << yytext << std::endl;
           if (!exit_status)
             exit_status = exit_scan;
         }
       else
         yylval->str->append (1, c);
     }

     \\x[0-9a-fA-F]{2}  {
       yylval->str->append (1, strtol (yytext + 2, 0, 16));
     }

     \\a        yylval->str->append (1, '\a');
     \\b        yylval->str->append (1, '\b');
     \\f        yylval->str->append (1, '\f');
     \\n        yylval->str->append (1, '\n');
     \\r        yylval->str->append (1, '\r');
     \\t        yylval->str->append (1, '\t');
     \\v        yylval->str->append (1, '\v');
     \\[\\""]   yylval->str->append (1, yytext[1]);
     \\.        {
       std::cerr
         << *yylloc << ": unrecognized escape: " << yytext << std::endl;
       if (!exit_status)
         exit_status = exit_scan;
     }


     [^\"\n\r\\]+      yylval->str->append (yytext, yyleng);

     {eol}+    yylloc->line (yyleng); yylval->str->append (yyleng, '\n');

     <<EOF>> {
       std::cerr
         << *yylloc << ": unexpected end of file in a string" << std::endl;
       if (!exit_status)
         exit_status = exit_scan;

       BEGIN INITIAL;
       return STRING;
     }
}

%%
//>>
/* Start reading FNAME. */

void
scan_open (const std::string &name)
{
  yyin = fopen (name.c_str (), "r");
  current_file = name;

  if (!yyin)
    {
      std::cerr
        << "cannot open `" << name << "': " << strerror (errno) << std::endl;
      exit (1);
    }
}

void
scan_close (void)
{
  fclose (yyin);
}



reply via email to

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