scan_c.l
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:14k
源码类别:

SQL Server

开发平台:

Unix_Linux

  1. %{
  2. /*
  3.  *  scan_c.l - scanner-extractor of GNU SQL/C compiler
  4.  *            
  5.  *  This file is a part of GNU SQL Server
  6.  *
  7.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  8.  *  Developed at the Institute of System Programming
  9.  *  This file is written by Michael Kimelman.
  10.  * 
  11.  *  This program is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2 of the License, or
  14.  *  (at your option) any later version.
  15.  *
  16.  *  This program is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU General Public License
  22.  *  along with this program; if not, write to the Free Software
  23.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  24.  *
  25.  *  Contact:  gss@ispras.ru
  26.  *
  27.  */
  28. /* $Id: scan_c.l,v 1.247 1997/04/21 14:26:13 kml Exp $ */
  29. #include "xmem.h"
  30. #include "gsqltrn.h"
  31. #include "sql_decl.h"
  32. #include "procname.h"
  33. #include <assert.h>
  34. #define SWITCH_COND(cond)  { save_condition();BEGIN(cond);}
  35. #define REST_COND            rest_condition();
  36. #define SCANNER_NAME      yylex_extractor
  37. #ifdef YY_DECL
  38. #  undef YY_DECL
  39. #endif
  40. #define YY_DECL           int SCANNER_NAME(void)
  41. YY_DECL;
  42. #define YY_USER_INIT      { BEGIN(START_CONDITION); line_num=1; }
  43. #define YY_USER_ACTION    if(yy_flex_debug){ 
  44.   fprintf(stderr,"nCurrent lex state=%dn",yy_start);}
  45. #define SQL_PROC(code)  if(code){file_pos=line_num; return 1<<code;}
  46. static str_buf c_scanner_buffer={0,0,NULL};
  47. #define sql_str(s,l)  buffer_string(&c_scanner_buffer,s,l)
  48. /* defined in main routine */
  49. int open_file(FILE **f,char *ext);
  50. static void  save_condition __P((void));
  51. static void  rest_condition __P((void));
  52. #ifndef START_CONDITION
  53. #  define START_CONDITION   scan_mode_state
  54. #endif
  55. #define BEGIN_MODE(v)    { BEGIN(v); scan_mode_state=v; }
  56. static char *statement_scanner_buffer=NULL;
  57. static int   line_num=1;
  58. static int   io_diff=0;
  59. static char *progname_out=NULL;
  60. static int   bline=1; 
  61. #define APPEND_BUFFER { sql_str(yytext,yyleng);} 
  62. #define POP_BUFFER pop_cl_buffer()
  63. void
  64. pop_cl_buffer(void)
  65. {
  66.   register char *b=sql_str(NULL,0);
  67.   statement_scanner_buffer=b?savestring(b):NULL;
  68. }
  69. %}
  70. %x C_lang c_comment C_str
  71. %x ESQL
  72. %x MOD SCH SQL
  73. %x SQL_str SQL_ident SQL_comment
  74. WS              [ tf]+
  75. NNS             [^A-Za-z0-9_]
  76. OPTWS           [ tf]*
  77. NOT_WS          [^ tfn]
  78. LET             [A-Za-z]
  79. SQL_STRT        ((EXEC[ t]+SQL)|("$"))
  80. %%
  81.     static int esql_caller = 0;
  82.     static int rout_title  = 0;
  83.     int comment_caller     = 0;
  84.     int first_start        = yy_init;
  85.     int with_grant_options = 0;
  86.     
  87.     #ifdef FLEX_DEBUG
  88.       yy_flex_debug=client_scanner_debug;
  89.     #endif
  90.   /*********************************************
  91.    *                C lexics                   *
  92.    *********************************************/
  93. <INITIAL,C_lang>^([ t]*{SQL_STRT})[ tnrf] {
  94.                           esql_caller=C_lang;
  95.                           bline=line_num;
  96.                           BEGIN_MODE(ESQL);
  97. }
  98. <C_lang>"/*"           {
  99.                           ECHO;
  100.   comment_caller=C_lang;
  101.   BEGIN_MODE(c_comment);
  102. }
  103. <C_lang>"              {
  104.                           ECHO;
  105.   BEGIN_MODE(C_str);
  106. }
  107. <INITIAL,C_lang>^([ t]*{SQL_STRT})[^ tnrf] |
  108. <C_lang>^.              { ECHO; }
  109. <INITIAL,C_lang>n      { ECHO; line_num++; }
  110.   /*********************************************
  111.    *               C string recognizer         *
  112.    *********************************************/
  113. <C_str>"                { ECHO; BEGIN_MODE(C_lang); }
  114. <C_str>\"              { ECHO; }
  115. <C_str>\n              { ECHO; ++line_num; }
  116. <C_str>\?.              { ECHO; }
  117. <C_str>n                { 
  118.                            ECHO;
  119.                            yyerror("Unterminated C string");
  120.                            BEGIN_MODE(C_lang);
  121.                          }
  122.   /*********************************************
  123.    *             C comment recornizer          *
  124.    *********************************************/
  125. <c_comment>[^*n]*         { if (comment_caller == C_lang) { ECHO; } }
  126. <c_comment>"*"+[^*/n]*  { if (comment_caller == C_lang) { ECHO; } }
  127. <c_comment>n               { if (comment_caller == C_lang) { ECHO; }
  128.                               line_num++;
  129.     }
  130. <c_comment>"*"+"/"        { if (comment_caller == C_lang)
  131. {
  132.   ECHO; 
  133. }
  134.       BEGIN_MODE(comment_caller);
  135.     }
  136.   /*********************************************
  137.    *        lexics of embedded SQL in C        *
  138.    *********************************************/
  139. <ESQL>/*              { if(esql_caller==C_lang)
  140.     {
  141.       comment_caller=ESQL;
  142.       BEGIN_MODE(c_comment);
  143.     }
  144.                           else
  145.     yyerror("Lex: Unrecognizable literal'/*'n");
  146. }
  147. <ESQL>;                 { 
  148.                           BEGIN_MODE(esql_caller);
  149.   POP_BUFFER;
  150.   SQL_PROC(ESQL); 
  151. }
  152.   /*********************************************
  153.    *          embedded SQL lexics              *
  154.    *********************************************/
  155. <INITIAL,SQL,MOD>MODULE/{NNS}  {
  156.                            BEGIN_MODE(MOD);
  157.    APPEND_BUFFER;
  158.  }
  159. <MOD>DECLARE/{NNS}       { 
  160.                            POP_BUFFER;
  161.    APPEND_BUFFER;
  162.    SQL_PROC(MOD);
  163.  }
  164. <MOD>PROCEDURE/{NNS}     {
  165.    rout_title=1;
  166.    POP_BUFFER;
  167.    APPEND_BUFFER;
  168.    SQL_PROC(MOD);
  169.  }
  170. <MOD>";"          {
  171.                            APPEND_BUFFER;
  172.    if(rout_title)
  173.      rout_title=0;
  174.    else
  175.      {
  176.        POP_BUFFER;
  177.        SQL_PROC(MOD);
  178.      } 
  179.  }
  180.   /*********************************************
  181.    *          clean  SQL SCH lexic             *
  182.    *********************************************/
  183. <INITIAL,SQL,SCH>((CREATE)|(ALTER)|(DROP))/{NNS} {
  184.                             {
  185.                               BEGIN_MODE(SCH);
  186.                               POP_BUFFER;
  187.                               APPEND_BUFFER;
  188.                               if(first_start)
  189.                                 first_start=0;
  190.                               else
  191.                                 {
  192.                                   SQL_PROC(SCH);
  193.                                 }
  194.                             }                    }
  195. <SCH>WITH/{NNS}          {
  196.    APPEND_BUFFER;
  197.                            with_grant_options=1;
  198.  }
  199. <SCH>GRANT/{NNS}         {
  200.                            if(with_grant_options)
  201.                              {
  202.        APPEND_BUFFER;
  203.        with_grant_options=0;
  204.      }
  205.                            else
  206.                              {
  207.        POP_BUFFER;
  208.        APPEND_BUFFER;
  209.        SQL_PROC(SCH);
  210.      }
  211.  }
  212. <SCH>REVOKE/{NNS}        {
  213.                            POP_BUFFER;
  214.    APPEND_BUFFER;
  215.    SQL_PROC(SCH);
  216.  }
  217. <SCH><<EOF>>          {
  218.                            POP_BUFFER;
  219.                            BEGIN(INITIAL);
  220.    SQL_PROC(SCH);
  221.  }
  222.   /*********************************************
  223.    *          common SQL  keywords             *
  224.    *********************************************/
  225. {WS}            /* do nothing */;
  226. <ESQL,MOD,SCH>{WS}  { APPEND_BUFFER; }
  227. <ESQL,MOD,SCH>'  {
  228.                            APPEND_BUFFER;
  229.    SWITCH_COND(SQL_str);
  230.  }
  231. <ESQL,MOD,SCH>"  {
  232.                            APPEND_BUFFER;
  233.    SWITCH_COND(SQL_ident);
  234.  }
  235. <INITIAL,ESQL,MOD,SCH>"-"{2} {
  236.                            SWITCH_COND(SQL_comment);  
  237.  }
  238. <ESQL,MOD,SCH>n  {
  239.                            APPEND_BUFFER;
  240.    line_num++; 
  241.  }
  242. <ESQL,MOD,SCH>.  { 
  243.                            APPEND_BUFFER;
  244.  }
  245.   /*********************************************
  246.    *             SQL string recognizer         *
  247.    *********************************************/
  248. <SQL_str>'{2}           { APPEND_BUFFER; }
  249. <SQL_str>n              {
  250.                            yyerror(" Unterminated SQL string ");
  251.            line_num++; 
  252.    REST_COND;
  253.          }
  254. <SQL_str>[^'n]+        { APPEND_BUFFER; }
  255. <SQL_str>'              {
  256.                            APPEND_BUFFER;
  257.                            REST_COND;
  258.  }
  259.   /*********************************************
  260.    *             SQL string recognizer         *
  261.    *********************************************/
  262. <SQL_ident>n              {
  263.                            yyerror(" Unterminated SQL identifier ");
  264.            line_num++; 
  265.    REST_COND;
  266.          }
  267. <SQL_ident>[^"n]+        { APPEND_BUFFER; }
  268. <SQL_ident>"{2}           { APPEND_BUFFER; }
  269. <SQL_ident>"              {
  270.    APPEND_BUFFER ;
  271.                            REST_COND;
  272.  }
  273.   /*********************************************
  274.    *             SQL comment recognizer        *
  275.    *********************************************/
  276. <SQL_comment>.      /* do nothing */;
  277. <SQL_comment>n          {
  278.                            line_num++;
  279.    REST_COND;
  280.  }
  281. .  { 
  282.                            ECHO;
  283.    BEGIN_MODE(C_lang);
  284.  }
  285. %%
  286. typedef struct save_yy_cond {
  287.       int yy_cond;
  288.       struct save_yy_cond *nxt;
  289.     } *sv_ys_ptr;
  290. static sv_ys_ptr save_yy_start=NULL;
  291. static void
  292. save_condition (void)
  293. {
  294.   register sv_ys_ptr nptr=(sv_ys_ptr)xmalloc(sizeof(struct save_yy_cond));
  295.   nptr->yy_cond=yy_start;
  296.   nptr->nxt=save_yy_start;
  297.   save_yy_start=nptr;
  298. #ifdef FLEX_DEBUG
  299.   if(yy_flex_debug)
  300.     fprintf(stderr,"n Lex: save condition :%d => (%d)n",
  301.             yy_start,nptr->yy_cond);
  302. #endif
  303. }
  304. static void
  305. rest_condition(void)
  306. {
  307.   register sv_ys_ptr nptr=save_yy_start;
  308.   if(nptr==NULL)
  309.     fatal("Lex: Impossible restore conditions before save it !",NULL);
  310.   yy_start=nptr->yy_cond;
  311.   save_yy_start=nptr->nxt;
  312. #ifdef FLEX_DEBUG
  313.   if(yy_flex_debug)
  314.     fprintf(stderr,"n Lex: restore condition :%d <=(%d)n",
  315.             yy_start,nptr->yy_cond);
  316. #endif
  317.   xfree(nptr);
  318. }
  319. static struct
  320. {
  321.   char *mode;
  322.   char *ext;
  323.   int   state;
  324. } scan_modes[] =
  325.   {"0"     ,"? ?",INITIAL},
  326.   {"SQL"   ,"sql",SQL},
  327.   {"MODULE","sql",MOD},
  328.   {"SCHEMA","sql",SCH},
  329.   {"C"     ,"ec" ,C_lang},
  330.   {"DMP"   ,"trl",-1}
  331. };
  332. void
  333. client_scan_mode(int *p,char *s)
  334.   register int k;
  335.   if(!s)
  336.     return;
  337.   for(k=sizeof(scan_modes)/sizeof(*scan_modes);k--;)
  338.     if(0==strcmp(s,scan_modes[k].mode))
  339.        break;
  340.   *p=scan_modes[k].state;
  341. }
  342. static void
  343. outtype(char *text,int ins_directives)
  344. {
  345.   char *p;
  346.   if (ins_directives & 1)
  347.     fprintf (yyout,"#line %d "%s" n", line_num + ( ++ io_diff),
  348.      progname_out);
  349.   if (text)
  350.     for (p = text; *p ; p++)
  351.       if (*p != 'n')
  352.         putc(*p,yyout);
  353.       else
  354.         {
  355.           if (ins_directives & 4)
  356.             {
  357. #if __STDC__   /* we assume produced code will be compiled by the same compiler */
  358.               fputs(""nt"",yyout);
  359.               io_diff++;
  360. #else
  361.               while (*p == ' ' || *p == 'n' || *p == 't') p++;
  362.               putc(' ',yyout); p--;
  363. #endif
  364.             }
  365.           else
  366.             {
  367.               putc('n',yyout);
  368.               io_diff++;
  369.             }
  370.         }
  371.   if (ins_directives & 2)
  372.     {
  373.       fprintf(yyout,"#line %d "%s" n",line_num,progname);
  374.       io_diff++;
  375.     }
  376. }
  377. int
  378. scanner (void)
  379. {
  380.   extern int open_file  __P((FILE ** f, char *ext));
  381.   int sm, oldsm;
  382.   sm = 0;
  383.   oldsm = scan_mode_state;
  384.   
  385.   if ( ( yyin = fopen (progname, "r") ) == NULL )
  386.     {
  387.       yyerror ("can't open input file");
  388.       return 0;
  389.     }
  390.   if (open_file (&yyout, "c") )
  391.     {
  392.       char b[120];
  393.       strcpy (b, sql_prg);
  394.       strcat (b, ".c");
  395.       progname_out = savestring (b);
  396.     }
  397.   else
  398.     yyfatal ("Can't create .c output file");
  399.   if (scan_mode_state == INITIAL)
  400.     {
  401.       register i4_t k;
  402.       register char *pn = progname+strlen(progname);
  403.       for (k = sizeof(scan_modes)/sizeof(*scan_modes); k--; )
  404.         if (0 == strcmp(pn - strlen(scan_modes[k].ext),scan_modes[k].ext))
  405.   break;
  406.       scan_mode_state = scan_modes[k].state;
  407.     }
  408. #if 0  
  409.   /*
  410.    * analyzing for dump extension - 
  411.    * may be load tree dump and continue processing from dumping point
  412.    */
  413.   if (scan_mode_state == INITIAL)
  414.     {
  415.       register int k;
  416.       register char *pn = progname+strlen(progname);
  417.       for (k = 0; compiler_passes[k].sname; k++)
  418.         if (0 == strcmp(pn - strlen(compiler_passes[k].ext),compiler_passes[k].ext))
  419.   { 
  420.     scan_mode_state = -1;
  421.     break;
  422.   }
  423.     }
  424. #endif  
  425.   yy_init = 1;
  426.   io_diff = 0;
  427.   line_num = 1;
  428.   outtype ("/* This file is created automatically by gsql compiler */n"
  429.    "#include <gnusql/sql.h>n"
  430.    "#include "",0);
  431.   outtype (sql_prg,0);
  432.   outtype (".Sc"nn",2);
  433.   while (SCANNER_NAME () )
  434.     {
  435.       extern char *prepare_statement(char *a,i4_t b,char **repl);
  436.       char *repl = NULL;
  437.       if (sm == 0)
  438. {
  439.   if(scan_mode_state == SCH)
  440.             {
  441.               int ln = line_num;
  442.               line_num = 1;
  443.               outtype ("n"
  444.                        "#include "dyn_funcs.h"n"
  445.                        "n"
  446.                        "int main(int argc, char **argv) {n", 1);
  447.               line_num = ln ;
  448.             }
  449.   sm = scan_mode_state;
  450. }
  451.       else
  452. assert ((sm == scan_mode_state) || (sm == INITIAL));
  453.       if (statement_scanner_buffer == NULL)
  454. yyfatal ( "Unexpected null input line");
  455.       if (sm == SCH) /* if we scan schema - there is no need to compile */
  456.         {            /* anything now - let's do it all at run time      */
  457.           outtype ("  SQL__execute_immediate ("", 0);
  458.           outtype (statement_scanner_buffer, 4);
  459.           outtype ("  ");n"
  460.                    "  if(SQLCODE>0)n"
  461.                    "    fprintf(stderr,"SQL warning:%s\n",gsqlca.errmsg);n"
  462.                    "  if(SQLCODE<0){n"
  463.                    "    fprintf(stderr,"SQL error:%s\n",gsqlca.errmsg);n"
  464.                    "    goto errexit;n"
  465.                    "  }n"
  466.                    , 0);
  467.         }
  468.       else if ( ! prepare_statement (statement_scanner_buffer, bline,
  469.                                      (sm == MOD? NULL:&repl)) )
  470. return 0;
  471.       io_diff -= line_num - bline;
  472.       if (sm != MOD)
  473.         outtype (repl, (sm == SCH) ? 0 : 3 );
  474.       bline = line_num;
  475.     }
  476.   if (sm == SCH)
  477.     outtype ("n"
  478.              "  " CALL_COMMIT_str "n"
  479.              "  return 0;n"
  480.              " errexit:n"
  481.              "  " CALL_ROLLBACK_str "n"
  482.              "  return SQLCODE;n"
  483.              "}n"
  484.              "/* end of create schema routine */n"
  485.              "n", 0);
  486.   scan_mode_state = oldsm;
  487.   if (yyin != stdin )
  488.     fclose (yyin);
  489.   fclose (yyout);
  490.   return 1;
  491. }