[BACK]Return to scan.l CVS log [TXT][DIR] Up to [local] / src / usr.bin / lex

Diff for /src/usr.bin/lex/scan.l between version 1.9 and 1.10

version 1.9, 2006/12/06 05:03:29 version 1.10, 2015/11/19 19:43:40
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
   
 /* scan.l - scanner for flex input */  /* scan.l - scanner for flex input -*-C-*- */
   
 %{  %{
 /*-  /*  Copyright (c) 1990 The Regents of the University of California. */
  * Copyright (c) 1990 The Regents of the University of California.  /*  All rights reserved. */
  * All rights reserved.  
  *  
  * This code is derived from software contributed to Berkeley by  
  * Vern Paxson.  
  *  
  * The United States Government has rights in this work pursuant  
  * to contract no. DE-AC03-76SF00098 between the United States  
  * Department of Energy and the University of California.  
  *  
  * Redistribution and use in source and binary forms, with or without  
  * modification, are permitted provided that the following conditions  
  * are met:  
  *  
  * 1. Redistributions of source code must retain the above copyright  
  *    notice, this list of conditions and the following disclaimer.  
  * 2. Redistributions in binary form must reproduce the above copyright  
  *    notice, this list of conditions and the following disclaimer in the  
  *    documentation and/or other materials provided with the distribution.  
  *  
  * Neither the name of the University nor the names of its contributors  
  * may be used to endorse or promote products derived from this software  
  * without specific prior written permission.  
  *  
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR  
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED  
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR  
  * PURPOSE.  
  */  
   
 /* $Header$ */  /*  This code is derived from software contributed to Berkeley by */
   /*  Vern Paxson. */
   
   /*  The United States Government has rights in this work pursuant */
   /*  to contract no. DE-AC03-76SF00098 between the United States */
   /*  Department of Energy and the University of California. */
   
   /*  This file is part of flex. */
   
   /*  Redistribution and use in source and binary forms, with or without */
   /*  modification, are permitted provided that the following conditions */
   /*  are met: */
   
   /*  1. Redistributions of source code must retain the above copyright */
   /*     notice, this list of conditions and the following disclaimer. */
   /*  2. Redistributions in binary form must reproduce the above copyright */
   /*     notice, this list of conditions and the following disclaimer in the */
   /*     documentation and/or other materials provided with the distribution. */
   
   /*  Neither the name of the University nor the names of its contributors */
   /*  may be used to endorse or promote products derived from this software */
   /*  without specific prior written permission. */
   
   /*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
   /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
   /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
   /*  PURPOSE. */
   
 #include "flexdef.h"  #include "flexdef.h"
 #include "parse.h"  #include "parse.h"
   extern bool tablesverify, tablesext;
   extern int trlcontxt; /* Set in  parse.y for each rule. */
   extern const char *escaped_qstart, *escaped_qend;
   
 #define ACTION_ECHO add_action( yytext )  #define ACTION_ECHO add_action( yytext )
 #define ACTION_IFDEF(def, should_define) \  #define ACTION_IFDEF(def, should_define) \
Line 46 
Line 47 
                 action_define( def, 1 ); \                  action_define( def, 1 ); \
         }          }
   
   #define ACTION_ECHO_QSTART add_action (escaped_qstart)
   #define ACTION_ECHO_QEND   add_action (escaped_qend)
   
   #define ACTION_M4_IFDEF(def, should_define) \
       do{ \
           if ( should_define ) \
               buf_m4_define( &m4defs_buf, def, NULL);\
           else \
               buf_m4_undefine( &m4defs_buf, def);\
       } while(0)
   
 #define MARK_END_OF_PROLOG mark_prolog();  #define MARK_END_OF_PROLOG mark_prolog();
   
 #define YY_DECL \  #define YY_DECL \
Line 56 
Line 68 
         return CHAR;          return CHAR;
   
 #define RETURNNAME \  #define RETURNNAME \
         strlcpy( nmstr, yytext, sizeof nmstr); \          if(yyleng < MAXLINE) \
            { \
           strlcpy( nmstr, yytext, sizeof nmstr ); \
            } \
           else \
            { \
              synerr(_("Input line too long\n")); \
              FLEX_EXIT(EXIT_FAILURE);  \
            }  \
         return NAME;          return NAME;
   
 #define PUT_BACK_STRING(str, start) \  #define PUT_BACK_STRING(str, start) \
Line 70 
Line 90 
 #define CHECK_YYMORE(str) \  #define CHECK_YYMORE(str) \
         if ( all_lower( str ) ) \          if ( all_lower( str ) ) \
                 yymore_used = true;                  yymore_used = true;
   
   #define YY_USER_INIT \
           if ( getenv("POSIXLY_CORRECT") ) \
                   posix_compat = true;
   
 %}  %}
   
 %option caseless nodefault outfile="scan.c" stack noyy_top_state  %option caseless nodefault stack noyy_top_state
 %option nostdinit  %option nostdinit
   
 %x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE  %x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
 %x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION  %x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION
 %x OPTION LINEDIR  %x OPTION LINEDIR CODEBLOCK_MATCH_BRACE
   %x GROUP_WITH_PARAMS
   %x GROUP_MINUS_PARAMS
   %x EXTENDED_COMMENT
   %x COMMENT_DISCARD
   
 WS              [[:blank:]]+  WS              [[:blank:]]+
 OPTWS           [[:blank:]]*  OPTWS           [[:blank:]]*
 NOT_WS          [^[:blank:]\n]  NOT_WS          [^[:blank:]\r\n]
   
 NL              \r?\n  NL              \r?\n
   
Line 94 
Line 123 
   
 FIRST_CCL_CHAR  ([^\\\n]|{ESCSEQ})  FIRST_CCL_CHAR  ([^\\\n]|{ESCSEQ})
 CCL_CHAR        ([^\\\n\]]|{ESCSEQ})  CCL_CHAR        ([^\\\n\]]|{ESCSEQ})
 CCL_EXPR        ("[:"[[:alpha:]]+":]")  CCL_EXPR        ("[:"^?[[:alpha:]]+":]")
   
 LEXOPT          [aceknopr]  LEXOPT          [aceknopr]
   
   M4QSTART    "[["
   M4QEND      "]]"
   
 %%  %%
         static int bracelevel, didadef, indented_code;          static int bracelevel, didadef, indented_code;
         static int doing_rule_action = false;          static int doing_rule_action = false;
         static int option_sense;          static int option_sense;
   
         int doing_codeblock = false;          int doing_codeblock = false;
         int i;          int i, brace_depth=0, brace_start_line=0;
         Char nmdef[MAXLINE], myesc();          Char nmdef[MAXLINE];
   
   
 <INITIAL>{  <INITIAL>{
Line 120 
Line 152 
                         indented_code = false;                          indented_code = false;
                         BEGIN(CODEBLOCK);                          BEGIN(CODEBLOCK);
                         }                          }
       ^"%top"[[:blank:]]*"{"[[:blank:]]*{NL}    {
                   brace_start_line = linenum;
                   ++linenum;
                   buf_linedir( &top_buf, infilename?infilename:"<stdin>", linenum);
                   brace_depth = 1;
                   yy_push_state(CODEBLOCK_MATCH_BRACE);
               }
   
       ^"%top".*   synerr( _("malformed '%top' directive") );
   
         {WS}            /* discard */          {WS}            /* discard */
   
         ^"%%".*         {          ^"%%".*         {
Line 140 
Line 181 
         ^"%"{LEXOPT}{OPTWS}[[:digit:]]*{OPTWS}{NL}      ++linenum; /* ignore */          ^"%"{LEXOPT}{OPTWS}[[:digit:]]*{OPTWS}{NL}      ++linenum; /* ignore */
         ^"%"{LEXOPT}{WS}.*{NL}  ++linenum;      /* ignore */          ^"%"{LEXOPT}{WS}.*{NL}  ++linenum;      /* ignore */
   
           /* xgettext: no-c-format */
         ^"%"[^sxaceknopr{}].*   synerr( _( "unrecognized '%' directive" ) );          ^"%"[^sxaceknopr{}].*   synerr( _( "unrecognized '%' directive" ) );
   
         ^{NAME}         {          ^{NAME}         {
                           if(yyleng < MAXLINE)
                            {
                         strlcpy( nmstr, yytext, sizeof nmstr );                          strlcpy( nmstr, yytext, sizeof nmstr );
                            }
                           else
                            {
                              synerr( _("Definition name too long\n"));
                              FLEX_EXIT(EXIT_FAILURE);
                            }
   
                         didadef = false;                          didadef = false;
                         BEGIN(PICKUPDEF);                          BEGIN(PICKUPDEF);
                         }                          }
Line 157 
Line 208 
 <COMMENT>{  <COMMENT>{
         "*/"            ACTION_ECHO; yy_pop_state();          "*/"            ACTION_ECHO; yy_pop_state();
         "*"             ACTION_ECHO;          "*"             ACTION_ECHO;
         [^*\n]+         ACTION_ECHO;      {M4QSTART}  ACTION_ECHO_QSTART;
         [^*\n]*{NL}     ++linenum; ACTION_ECHO;      {M4QEND}    ACTION_ECHO_QEND;
           [^*\n]      ACTION_ECHO;
           {NL}        ++linenum; ACTION_ECHO;
 }  }
   
   <COMMENT_DISCARD>{
           /* This is the same as COMMENT, but is discarded rather than output. */
           "*/"            yy_pop_state();
       "*"         ;
           [^*\n]      ;
           {NL}        ++linenum;
   }
   
   <EXTENDED_COMMENT>{
       ")"         yy_pop_state();
       [^\n\)]+      ;
       {NL}        ++linenum;
   }
   
 <LINEDIR>{  <LINEDIR>{
         \n              yy_pop_state();          \n              yy_pop_state();
         [[:digit:]]+    linenum = myctoi( yytext );          [[:digit:]]+    linenum = myctoi( yytext );
Line 176 
Line 243 
 <CODEBLOCK>{  <CODEBLOCK>{
         ^"%}".*{NL}     ++linenum; BEGIN(INITIAL);          ^"%}".*{NL}     ++linenum; BEGIN(INITIAL);
   
         {NAME}|{NOT_NAME}|.     ACTION_ECHO;      {M4QSTART}  ACTION_ECHO_QSTART;
       {M4QEND}    ACTION_ECHO_QEND;
           .               ACTION_ECHO;
   
         {NL}            {          {NL}            {
                         ++linenum;                          ++linenum;
Line 186 
Line 255 
                         }                          }
 }  }
   
   <CODEBLOCK_MATCH_BRACE>{
       "}"     {
                   if( --brace_depth == 0){
                       /* TODO: Matched. */
                       yy_pop_state();
                   }else
                       buf_strnappend(&top_buf, yytext, yyleng);
               }
   
       "{"     {
                   brace_depth++;
                   buf_strnappend(&top_buf, yytext, yyleng);
               }
   
       {NL}    {
                   ++linenum;
                   buf_strnappend(&top_buf, yytext, yyleng);
               }
   
       {M4QSTART}  buf_strnappend(&top_buf, escaped_qstart, strlen(escaped_qstart));
       {M4QEND}    buf_strnappend(&top_buf, escaped_qend, strlen(escaped_qend));
   
       [^{}\r\n]  {
                   buf_strnappend(&top_buf, yytext, yyleng);
                  }
   
       <<EOF>>     {
                   linenum = brace_start_line;
                   synerr(_("Unmatched '{'"));
                   yyterminate();
                   }
   }
   
   
 <PICKUPDEF>{  <PICKUPDEF>{
         {WS}            /* separates name and definition */          {WS}            /* separates name and definition */
   
         {NOT_WS}.*      {          {NOT_WS}[^\r\n]*        {
                         strlcpy( (char *) nmdef, yytext, sizeof nmdef);                          if(yyleng < MAXLINE)
                            {
                           strlcpy( (char *) nmdef, yytext, sizeof nmdef );
                            }
                           else
                            {
                              format_synerr( _("Definition value for {%s} too long\n"), nmstr);
                              FLEX_EXIT(EXIT_FAILURE);
                            }
                         /* Skip trailing whitespace. */                          /* Skip trailing whitespace. */
                         for ( i = strlen( (char *) nmdef ) - 1;                          for ( i = strlen( (char *) nmdef ) - 1;
                               i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t');                                i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t');
Line 227 
Line 336 
   
         align           long_align = option_sense;          align           long_align = option_sense;
         always-interactive      {          always-interactive      {
                         action_define( "YY_ALWAYS_INTERACTIVE", option_sense );                          ACTION_M4_IFDEF( "M4""_YY_ALWAYS_INTERACTIVE", option_sense );
               interactive = option_sense;
                         }                          }
         array           yytext_is_array = option_sense;          array           yytext_is_array = option_sense;
       ansi-definitions ansi_func_defs = option_sense;
       ansi-prototypes  ansi_func_protos = option_sense;
         backup          backing_up_report = option_sense;          backup          backing_up_report = option_sense;
         batch           interactive = ! option_sense;          batch           interactive = ! option_sense;
       bison-bridge     bison_bridge_lval = option_sense;
       bison-locations  { if((bison_bridge_lloc = option_sense))
                               bison_bridge_lval = true;
                        }
         "c++"           C_plus_plus = option_sense;          "c++"           C_plus_plus = option_sense;
         caseful|case-sensitive          caseins = ! option_sense;          caseful|case-sensitive          sf_set_case_ins(!option_sense);
         caseless|case-insensitive       caseins = option_sense;          caseless|case-insensitive       sf_set_case_ins(option_sense);
         debug           ddebug = option_sense;          debug           ddebug = option_sense;
         default         spprdflt = ! option_sense;          default         spprdflt = ! option_sense;
         ecs             useecs = option_sense;          ecs             useecs = option_sense;
Line 249 
Line 365 
         input           ACTION_IFDEF("YY_NO_INPUT", ! option_sense);          input           ACTION_IFDEF("YY_NO_INPUT", ! option_sense);
         interactive     interactive = option_sense;          interactive     interactive = option_sense;
         lex-compat      lex_compat = option_sense;          lex-compat      lex_compat = option_sense;
           posix-compat    posix_compat = option_sense;
         main            {          main            {
                         action_define( "YY_MAIN", option_sense );                          ACTION_M4_IFDEF( "M4""_YY_MAIN", option_sense);
                         do_yywrap = ! option_sense;              /* Override yywrap */
               if( option_sense == true )
                   do_yywrap = false;
                         }                          }
         meta-ecs        usemecs = option_sense;          meta-ecs        usemecs = option_sense;
         never-interactive       {          never-interactive       {
                         action_define( "YY_NEVER_INTERACTIVE", option_sense );                          ACTION_M4_IFDEF( "M4""_YY_NEVER_INTERACTIVE", option_sense );
               interactive = !option_sense;
                         }                          }
         perf-report     performance_report += option_sense ? 1 : -1;          perf-report     performance_report += option_sense ? 1 : -1;
         pointer         yytext_is_array = ! option_sense;          pointer         yytext_is_array = ! option_sense;
         read            use_read = option_sense;          read            use_read = option_sense;
       reentrant   reentrant = option_sense;
         reject          reject_really_used = option_sense;          reject          reject_really_used = option_sense;
         stack           action_define( "YY_STACK_USED", option_sense );          stack           ACTION_M4_IFDEF( "M4""_YY_STACK_USED", option_sense );
         stdinit         do_stdinit = option_sense;          stdinit         do_stdinit = option_sense;
         stdout          use_stdout = option_sense;          stdout          use_stdout = option_sense;
         unput           ACTION_IFDEF("YY_NO_UNPUT", ! option_sense);      unistd      ACTION_IFDEF("YY_NO_UNISTD_H", ! option_sense);
           unput           ACTION_M4_IFDEF("M4""_YY_NO_UNPUT", ! option_sense);
         verbose         printstats = option_sense;          verbose         printstats = option_sense;
         warn            nowarn = ! option_sense;          warn            nowarn = ! option_sense;
         yylineno        do_yylineno = option_sense;          yylineno        do_yylineno = option_sense; ACTION_M4_IFDEF("M4""_YY_USE_LINENO", option_sense);
         yymore          yymore_really_used = option_sense;          yymore          yymore_really_used = option_sense;
         yywrap          do_yywrap = option_sense;          yywrap      do_yywrap = option_sense;
   
         yy_push_state   ACTION_IFDEF("YY_NO_PUSH_STATE", ! option_sense);          yy_push_state   ACTION_M4_IFDEF("M4""_YY_NO_PUSH_STATE", ! option_sense);
         yy_pop_state    ACTION_IFDEF("YY_NO_POP_STATE", ! option_sense);          yy_pop_state    ACTION_M4_IFDEF("M4""_YY_NO_POP_STATE", ! option_sense);
         yy_top_state    ACTION_IFDEF("YY_NO_TOP_STATE", ! option_sense);          yy_top_state    ACTION_M4_IFDEF("M4""_YY_NO_TOP_STATE", ! option_sense);
   
         yy_scan_buffer  ACTION_IFDEF("YY_NO_SCAN_BUFFER", ! option_sense);          yy_scan_buffer  ACTION_M4_IFDEF("M4""_YY_NO_SCAN_BUFFER", ! option_sense);
         yy_scan_bytes   ACTION_IFDEF("YY_NO_SCAN_BYTES", ! option_sense);          yy_scan_bytes   ACTION_M4_IFDEF("M4""_YY_NO_SCAN_BYTES", ! option_sense);
         yy_scan_string  ACTION_IFDEF("YY_NO_SCAN_STRING", ! option_sense);          yy_scan_string  ACTION_M4_IFDEF("M4""_YY_NO_SCAN_STRING", ! option_sense);
   
       yyalloc         ACTION_M4_IFDEF("M4""_YY_NO_FLEX_ALLOC", ! option_sense);
       yyrealloc       ACTION_M4_IFDEF("M4""_YY_NO_FLEX_REALLOC", ! option_sense);
       yyfree          ACTION_M4_IFDEF("M4""_YY_NO_FLEX_FREE", ! option_sense);
   
       yyget_debug     ACTION_M4_IFDEF("M4""_YY_NO_GET_DEBUG", ! option_sense);
       yyset_debug     ACTION_M4_IFDEF("M4""_YY_NO_SET_DEBUG", ! option_sense);
       yyget_extra     ACTION_M4_IFDEF("M4""_YY_NO_GET_EXTRA", ! option_sense);
       yyset_extra     ACTION_M4_IFDEF("M4""_YY_NO_SET_EXTRA", ! option_sense);
       yyget_leng      ACTION_M4_IFDEF("M4""_YY_NO_GET_LENG", ! option_sense);
       yyget_text      ACTION_M4_IFDEF("M4""_YY_NO_GET_TEXT", ! option_sense);
       yyget_lineno    ACTION_M4_IFDEF("M4""_YY_NO_GET_LINENO", ! option_sense);
       yyset_lineno    ACTION_M4_IFDEF("M4""_YY_NO_SET_LINENO", ! option_sense);
       yyget_in        ACTION_M4_IFDEF("M4""_YY_NO_GET_IN", ! option_sense);
       yyset_in        ACTION_M4_IFDEF("M4""_YY_NO_SET_IN", ! option_sense);
       yyget_out       ACTION_M4_IFDEF("M4""_YY_NO_GET_OUT", ! option_sense);
       yyset_out       ACTION_M4_IFDEF("M4""_YY_NO_SET_OUT", ! option_sense);
       yyget_lval      ACTION_M4_IFDEF("M4""_YY_NO_GET_LVAL", ! option_sense);
       yyset_lval      ACTION_M4_IFDEF("M4""_YY_NO_SET_LVAL", ! option_sense);
       yyget_lloc      ACTION_M4_IFDEF("M4""_YY_NO_GET_LLOC", ! option_sense);
       yyset_lloc      ACTION_M4_IFDEF("M4""_YY_NO_SET_LLOC", ! option_sense);
   
           extra-type      return OPT_EXTRA_TYPE;
         outfile         return OPT_OUTFILE;          outfile         return OPT_OUTFILE;
         prefix          return OPT_PREFIX;          prefix          return OPT_PREFIX;
         yyclass         return OPT_YYCLASS;          yyclass         return OPT_YYCLASS;
           header(-file)?      return OPT_HEADER;
           tables-file         return OPT_TABLES;
           tables-verify   {
                       tablesverify = option_sense;
                       if(!tablesext && option_sense)
                           tablesext = true;
                       }
   
   
         \"[^"\n]*\"     {          \"[^"\n]*\"     {
                         strlcpy( nmstr, yytext + 1, sizeof nmstr);                          if(yyleng-1 < MAXLINE)
                         if (nmstr[strlen(nmstr) - 1] == '"')                           {
                                 nmstr[strlen(nmstr) - 1] = '\0';                          strlcpy( nmstr, yytext + 1, sizeof nmstr );
                            }
                           else
                            {
                              synerr( _("Option line too long\n"));
                              FLEX_EXIT(EXIT_FAILURE);
                            }
                           if (nmstr[strlen( nmstr ) - 1] == '"')
                                   nmstr[strlen( nmstr ) - 1] = '\0';
                         return NAME;                          return NAME;
                         }                          }
   
Line 318 
Line 478 
                                 ACTION_ECHO;                                  ACTION_ECHO;
                         }                          }
   
         .*              ACTION_ECHO;          .               ACTION_ECHO;
         {NL}    ++linenum; ACTION_ECHO;          {NL}    ++linenum; ACTION_ECHO;
   
         <<EOF>>         {          <<EOF>>         {
Line 338 
Line 498 
                         BEGIN(PERCENT_BRACE_ACTION);                          BEGIN(PERCENT_BRACE_ACTION);
                         }                          }
   
         ^{OPTWS}"<"     BEGIN(SC); return '<';          ^{OPTWS}"<"         {
                           /* Allow "<" to appear in (?x) patterns. */
                           if (!sf_skip_ws())
                               BEGIN(SC);
                           return '<';
                       }
         ^{OPTWS}"^"     return '^';          ^{OPTWS}"^"     return '^';
         \"              BEGIN(QUOTE); return '"';          \"              BEGIN(QUOTE); return '"';
         "{"/[[:digit:]] BEGIN(NUM); return '{';          "{"/[[:digit:]] {
                           BEGIN(NUM);
                           if ( lex_compat || posix_compat )
                                   return BEGIN_REPEAT_POSIX;
                           else
                                   return BEGIN_REPEAT_FLEX;
                           }
         "$"/([[:blank:]]|{NL})  return '$';          "$"/([[:blank:]]|{NL})  return '$';
   
         {WS}"%{"                {          {WS}"%{"                {
Line 355 
Line 526 
                                 return '\n';                                  return '\n';
                                 }                                  }
                         }                          }
         {WS}"|".*{NL}   continued_action = true; ++linenum; return '\n';          {WS}"|".*{NL}   {
                           if (sf_skip_ws()){
                               /* We're in the middle of a (?x: ) pattern. */
                               /* Push back everything starting at the "|" */
                               size_t amt;
                               amt = strchr (yytext, '|') - yytext;
                               yyless(amt);
                           }
                           else {
                               continued_action = true;
                               ++linenum;
                               return '\n';
                           }
                       }
   
         ^{WS}"/*"       {          ^{WS}"/*"       {
                         yyless( yyleng - 2 );   /* put back '/', '*' */  
                         bracelevel = 0;                  if (sf_skip_ws()){
                         continued_action = false;                      /* We're in the middle of a (?x: ) pattern. */
                         BEGIN(ACTION);                      yy_push_state(COMMENT_DISCARD);
                   }
                   else{
                       yyless( yyleng - 2 );       /* put back '/', '*' */
                       bracelevel = 0;
                       continued_action = false;
                       BEGIN(ACTION);
                   }
                         }                          }
   
         ^{WS}           /* allow indented rules */          ^{WS}           /* allow indented rules */ ;
   
         {WS}            {          {WS}            {
                         /* This rule is separate from the one below because              if (sf_skip_ws()){
                          * otherwise we get variable trailing context, so                  /* We're in the middle of a (?x: ) pattern. */
                          * we can't build the scanner using -{f,F}.              }
                          */              else{
                         bracelevel = 0;                  /* This rule is separate from the one below because
                         continued_action = false;                   * otherwise we get variable trailing context, so
                         BEGIN(ACTION);                   * we can't build the scanner using -{f,F}.
                    */
                   bracelevel = 0;
                   continued_action = false;
                   BEGIN(ACTION);
   
                         if ( in_rule )                  if ( in_rule )
                                 {                      {
                                 doing_rule_action = true;                      doing_rule_action = true;
                                 in_rule = false;                      in_rule = false;
                                 return '\n';                      return '\n';
                                 }                      }
               }
                         }                          }
   
         {OPTWS}{NL}     {          {OPTWS}{NL}     {
                         bracelevel = 0;              if (sf_skip_ws()){
                         continued_action = false;                  /* We're in the middle of a (?x: ) pattern. */
                         BEGIN(ACTION);                  ++linenum;
                         unput( '\n' );  /* so <ACTION> sees it */              }
               else{
                   bracelevel = 0;
                   continued_action = false;
                   BEGIN(ACTION);
                   unput( '\n' );  /* so <ACTION> sees it */
   
                         if ( in_rule )                  if ( in_rule )
                                 {                      {
                                 doing_rule_action = true;                      doing_rule_action = true;
                                 in_rule = false;                      in_rule = false;
                                 return '\n';                      return '\n';
                                 }                      }
               }
                         }                          }
   
         ^{OPTWS}"<<EOF>>"       |          ^{OPTWS}"<<EOF>>"       |
Line 403 
Line 605 
         ^"%%".*         {          ^"%%".*         {
                         sectnum = 3;                          sectnum = 3;
                         BEGIN(SECT3);                          BEGIN(SECT3);
                           outn("/* Begin user sect3 */");
                         yyterminate(); /* to stop the parser */                          yyterminate(); /* to stop the parser */
                         }                          }
   
         "["({FIRST_CCL_CHAR}|{CCL_EXPR})({CCL_CHAR}|{CCL_EXPR})*        {          "["({FIRST_CCL_CHAR}|{CCL_EXPR})({CCL_CHAR}|{CCL_EXPR})*        {
                         int cclval;                          int cclval;
   
                         strlcpy( nmstr, yytext, sizeof nmstr);                          if(yyleng < MAXLINE)
                            {
                           strlcpy( nmstr, yytext, sizeof nmstr );
                            }
                           else
                            {
                              synerr( _("Input line too long\n"));
                              FLEX_EXIT(EXIT_FAILURE);
                            }
   
                         /* Check to see if we've already encountered this                          /* Check to see if we've already encountered this
                          * ccl.                           * ccl.
                          */                           */
                         if ( (cclval = ccllookup( (Char *) nmstr )) != 0 )                          if (0 /* <--- This "0" effectively disables the reuse of a
                      * character class (purely based on its source text).
                      * The reason it was disabled is so yacc/bison can parse
                      * ccl operations, such as ccl difference and union.
                      */
                   &&  (cclval = ccllookup( (Char *) nmstr )) != 0 )
                                 {                                  {
                                 if ( input() != ']' )                                  if ( input() != ']' )
                                         synerr( _( "bad character class" ) );                                          synerr( _( "bad character class" ) );
Line 439 
Line 655 
                                 return '[';                                  return '[';
                                 }                                  }
                         }                          }
       "{-}"       return CCL_OP_DIFF;
       "{+}"       return CCL_OP_UNION;
   
         "{"{NAME}"}"    {  
                         register Char *nmdefptr;  
                         Char *ndlookup();  
   
       /* Check for :space: at the end of the rule so we don't
        * wrap the expanded regex in '(' ')' -- breaking trailing
        * context.
        */
           "{"{NAME}"}"[[:space:]]?         {
                           Char *nmdefptr;
               int end_is_ws, end_ch;
   
               end_ch = yytext[yyleng-1];
               end_is_ws = end_ch != '}' ? 1 : 0;
   
                           if(yyleng-1 < MAXLINE)
                            {
                         strlcpy( nmstr, yytext + 1, sizeof nmstr );                          strlcpy( nmstr, yytext + 1, sizeof nmstr );
                         nmstr[yyleng - 2] = '\0';  /* chop trailing brace */                           }
                           else
                            {
                              synerr( _("Input line too long\n"));
                              FLEX_EXIT(EXIT_FAILURE);
                            }
   nmstr[yyleng - 2 - end_is_ws] = '\0';  /* chop trailing brace */
   
                         if ( (nmdefptr = ndlookup( nmstr )) == 0 )                          if ( (nmdefptr = ndlookup( nmstr )) == 0 )
                                 format_synerr(                                  format_synerr(
Line 455 
Line 689 
                         else                          else
                                 { /* push back name surrounded by ()'s */                                  { /* push back name surrounded by ()'s */
                                 int len = strlen( (char *) nmdefptr );                                  int len = strlen( (char *) nmdefptr );
                   if (end_is_ws)
                       unput(end_ch);
   
                                 if ( lex_compat || nmdefptr[0] == '^' ||                                  if ( lex_compat || nmdefptr[0] == '^' ||
                                      (len > 0 && nmdefptr[len - 1] == '$') )                                       (len > 0 && nmdefptr[len - 1] == '$')
                        || (end_is_ws && trlcontxt && !sf_skip_ws()))
                                         { /* don't use ()'s after all */                                          { /* don't use ()'s after all */
                                         PUT_BACK_STRING((char *) nmdefptr, 0);                                          PUT_BACK_STRING((char *) nmdefptr, 0);
   
Line 474 
Line 711 
                                 }                                  }
                         }                          }
   
       "/*"        {
                       if (sf_skip_ws())
                           yy_push_state(COMMENT_DISCARD);
                       else{
                           /* Push back the "*" and return "/" as usual. */
                           yyless(1);
                           return '/';
                       }
                   }
   
       "(?#"       {
                       if (lex_compat || posix_compat){
                           /* Push back the "?#" and treat it like a normal parens. */
                           yyless(1);
                           sf_push();
                           return '(';
                       }
                       else
                           yy_push_state(EXTENDED_COMMENT);
                   }
       "(?"        {
                       sf_push();
                       if (lex_compat || posix_compat)
                           /* Push back the "?" and treat it like a normal parens. */
                           yyless(1);
                       else
                           BEGIN(GROUP_WITH_PARAMS);
                       return '(';
                   }
       "("         sf_push(); return '(';
       ")"         sf_pop(); return ')';
   
         [/|*+?.(){}]    return (unsigned char) yytext[0];          [/|*+?.(){}]    return (unsigned char) yytext[0];
         .               RETURNCHAR;          .               RETURNCHAR;
 }  }
   
   
 <SC>{  <SC>{
           {OPTWS}{NL}{OPTWS}      ++linenum;      /* Allow blank lines & continuations */
         [,*]            return (unsigned char) yytext[0];          [,*]            return (unsigned char) yytext[0];
         ">"             BEGIN(SECT2); return '>';          ">"             BEGIN(SECT2); return '>';
         ">"/^           BEGIN(CARETISBOL); return '>';          ">"/^           BEGIN(CARETISBOL); return '>';
Line 505 
Line 775 
                         }                          }
 }  }
   
   <GROUP_WITH_PARAMS>{
       ":"     BEGIN(SECT2);
       "-"     BEGIN(GROUP_MINUS_PARAMS);
       i       sf_set_case_ins(1);
       s       sf_set_dot_all(1);
       x       sf_set_skip_ws(1);
   }
   <GROUP_MINUS_PARAMS>{
       ":"     BEGIN(SECT2);
       i       sf_set_case_ins(0);
       s       sf_set_dot_all(0);
       x       sf_set_skip_ws(0);
   }
   
 <FIRSTCCL>{  <FIRSTCCL>{
         "^"/[^-\]\n]    BEGIN(CCL); return '^';          "^"/[^-\]\n]    BEGIN(CCL); return '^';
Line 536 
Line 819 
         "[:space:]"     BEGIN(CCL); return CCE_SPACE;          "[:space:]"     BEGIN(CCL); return CCE_SPACE;
         "[:upper:]"     BEGIN(CCL); return CCE_UPPER;          "[:upper:]"     BEGIN(CCL); return CCE_UPPER;
         "[:xdigit:]"    BEGIN(CCL); return CCE_XDIGIT;          "[:xdigit:]"    BEGIN(CCL); return CCE_XDIGIT;
   
           "[:^alnum:]"    BEGIN(CCL); return CCE_NEG_ALNUM;
           "[:^alpha:]"    BEGIN(CCL); return CCE_NEG_ALPHA;
           "[:^blank:]"    BEGIN(CCL); return CCE_NEG_BLANK;
           "[:^cntrl:]"    BEGIN(CCL); return CCE_NEG_CNTRL;
           "[:^digit:]"    BEGIN(CCL); return CCE_NEG_DIGIT;
           "[:^graph:]"    BEGIN(CCL); return CCE_NEG_GRAPH;
           "[:^lower:]"    BEGIN(CCL); return CCE_NEG_LOWER;
           "[:^print:]"    BEGIN(CCL); return CCE_NEG_PRINT;
           "[:^punct:]"    BEGIN(CCL); return CCE_NEG_PUNCT;
           "[:^space:]"    BEGIN(CCL); return CCE_NEG_SPACE;
           "[:^upper:]"    BEGIN(CCL); return CCE_NEG_UPPER;
           "[:^xdigit:]"   BEGIN(CCL); return CCE_NEG_XDIGIT;
         {CCL_EXPR}      {          {CCL_EXPR}      {
                         format_synerr(                          format_synerr(
                                 _( "bad character class expression: %s" ),                                  _( "bad character class expression: %s" ),
Line 551 
Line 847 
                         }                          }
   
         ","             return ',';          ","             return ',';
         "}"             BEGIN(SECT2); return '}';          "}"             {
                           BEGIN(SECT2);
                           if ( lex_compat || posix_compat )
                                   return END_REPEAT_POSIX;
                           else
                                   return END_REPEAT_FLEX;
                           }
   
         .               {          .               {
                         synerr( _( "bad character inside {}'s" ) );                          synerr( _( "bad character inside {}'s" ) );
Line 584 
Line 886 
                         }                          }
         }          }
   
         {NAME}|{NOT_NAME}|.     ACTION_ECHO;      {M4QSTART}  ACTION_ECHO_QSTART;
       {M4QEND}    ACTION_ECHO_QEND;
       .           ACTION_ECHO;
         {NL}            {          {NL}            {
                         ++linenum;                          ++linenum;
                         ACTION_ECHO;                          ACTION_ECHO;
Line 605 
Line 909 
 <ACTION>{  <ACTION>{
         "{"             ACTION_ECHO; ++bracelevel;          "{"             ACTION_ECHO; ++bracelevel;
         "}"             ACTION_ECHO; --bracelevel;          "}"             ACTION_ECHO; --bracelevel;
         [^[:alpha:]_{}"'/\n]+   ACTION_ECHO;      {M4QSTART}  ACTION_ECHO_QSTART;
       {M4QEND}    ACTION_ECHO_QEND;
           [^[:alpha:]_{}"'/\n\[\]]+       ACTION_ECHO;
       [\[\]]      ACTION_ECHO;
         {NAME}          ACTION_ECHO;          {NAME}          ACTION_ECHO;
         "'"([^'\\\n]|\\.)*"'"   ACTION_ECHO; /* character constant */          "'"([^'\\\n]|\\.)*"'"   ACTION_ECHO; /* character constant */
         \"              ACTION_ECHO; BEGIN(ACTION_STRING);          \"              ACTION_ECHO; BEGIN(ACTION_STRING);
Line 627 
Line 934 
 <ACTION_STRING>{  <ACTION_STRING>{
         [^"\\\n]+       ACTION_ECHO;          [^"\\\n]+       ACTION_ECHO;
         \\.             ACTION_ECHO;          \\.             ACTION_ECHO;
         {NL}            ++linenum; ACTION_ECHO;          {NL}            ++linenum; ACTION_ECHO; BEGIN(ACTION);
         \"              ACTION_ECHO; BEGIN(ACTION);          \"              ACTION_ECHO; BEGIN(ACTION);
         .               ACTION_ECHO;          .               ACTION_ECHO;
 }  }
   
 <COMMENT,ACTION,ACTION_STRING><<EOF>>   {  <COMMENT,COMMENT_DISCARD,ACTION,ACTION_STRING><<EOF>>   {
                         synerr( _( "EOF encountered inside an action" ) );                          synerr( _( "EOF encountered inside an action" ) );
                         yyterminate();                          yyterminate();
                         }                          }
   
   <EXTENDED_COMMENT,GROUP_WITH_PARAMS,GROUP_MINUS_PARAMS><<EOF>>  {
                           synerr( _( "EOF encountered inside pattern" ) );
                           yyterminate();
                           }
   
 <SECT2,QUOTE,FIRSTCCL,CCL>{ESCSEQ}      {  <SECT2,QUOTE,FIRSTCCL,CCL>{ESCSEQ}      {
                         yylval = myesc( (Char *) yytext );                          yylval = myesc( (Char *) yytext );
Line 649 
Line 960 
   
   
 <SECT3>{  <SECT3>{
         .*(\n?)         ECHO;      {M4QSTART}  fwrite (escaped_qstart, 1, strlen(escaped_qstart), yyout);
       {M4QEND}    fwrite (escaped_qend, 1, strlen(escaped_qend), yyout);
           [^\[\]\n]*(\n?) ECHO;
           (.|\n)      ECHO;
         <<EOF>>         sectnum = 0; yyterminate();          <<EOF>>         sectnum = 0; yyterminate();
 }  }
   

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10