sqlp.l 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*****************************************************************************
  2. *
  3. * MODULE: SQL statement parser library
  4. *
  5. * AUTHOR(S): lex.l and yac.y were originaly taken from unixODBC and
  6. * probably written by Peter Harvey <pharvey@codebydesigns.com>,
  7. * modifications and other code by Radim Blazek
  8. *
  9. * PURPOSE: Parse input string containing SQL statement to
  10. * SQLPSTMT structure.
  11. * SQL parser may be used by simple database drivers.
  12. *
  13. * COPYRIGHT: (C) 2000 by the GRASS Development Team
  14. *
  15. * This program is free software under the GNU General Public
  16. * License (>=v2). Read the file COPYING that comes with GRASS
  17. * for details.
  18. *
  19. *****************************************************************************/
  20. /**************** C-CODE *****************/
  21. %{
  22. #include <grass/sqlp.h>
  23. #include "sqlp.tab.h"
  24. #include <string.h>
  25. #undef YY_INPUT
  26. #define YY_INPUT(b, r, ms) (r = my_yyinput(b, ms))
  27. %}
  28. /*************** LEX HEADER **************/
  29. %e 1200
  30. /**************** LEX BODY ****************/
  31. %%
  32. %{
  33. /***************************************
  34. * LITERALS KEYWORDS TOKENS
  35. ***************************************/
  36. /* following case insensitives are ugly
  37. but I do not know better at this time */
  38. %}
  39. [Aa][Dd][Dd] { return ADD; }
  40. [Aa][Ll][Tt][Ee][Rr] { return ALTER; }
  41. [Cc][Oo][Ll][Uu][Mm][Nn] { return COLUMN; }
  42. [Dd][Ee][Ll][Ee][Tt][Ee] { return DELETE; }
  43. [Ff][Rr][Oo][Mm] { return FROM; }
  44. [Ii][Nn][Ss][Ee][Rr][Tt] { return INSERT; }
  45. [Ii][Nn][Tt][Oo] { return INTO; }
  46. [Ss][Ee][Ll][Ee][Cc][Tt] { return SELECT; }
  47. [Ss][Ee][Tt] { return SET; }
  48. [Uu][Pp][Dd][Aa][Tt][Ee] { return UPDATE; }
  49. [Vv][Aa][Ll][Uu][Ee][Ss] { return VALUES; }
  50. [Ww][Hh][Ee][Rr][Ee] { return WHERE; }
  51. [Aa][Nn][Dd] { return AND; }
  52. [Cc][Rr][Ee][Aa][Tt][Ee] { return CREATE; }
  53. [Dd][Rr][Oo][Pp] { return DROP; }
  54. [Tt][Aa][Bb][Ll][Ee] { return TABLE; }
  55. [Nn][Uu][Ll][Ll] { return NULL_VALUE; }
  56. [Vv][Aa][Rr][Cc][Hh][Aa][Rr] { return VARCHAR; }
  57. [Ii][Nn][Tt] { return INT; }
  58. [Ii][Nn][Tt][Ee][Gg][Ee][Rr] { return INTEGER; }
  59. [Dd][Oo][Uu][Bb][Ll][Ee] { return DOUBLE; }
  60. [Pp][Rr][Ee][Cc][Ii][Ss][Ii][Oo][Nn] { return PRECISION; }
  61. [Dd][Aa][Tt][Ee] { return DATE; }
  62. [Tt][Ii][Mm][Ee] { return TIME; }
  63. [Oo][Rr] { return OR; }
  64. [Nn][Oo][Tt] { return NOT; }
  65. [Oo][Rr][Dd][Ee][Rr] { return ORDER; }
  66. [Bb][Yy] { return BY; }
  67. [Aa][Ss][Cc] { return ASC; }
  68. [Dd][Ee][Ss][Cc] { return DESC; }
  69. [Ii][Ss] { return IS; }
  70. [Ll][Ii][Kk][Ee] {
  71. yylval.strval = (char*)strdup("~");
  72. return COMPARISON_OPERATOR;
  73. }
  74. %{
  75. /* [Dd][Ii][Ss][Tt][Ii][Nn][Cc][Tt] { return DISTINCT; } */
  76. /***************************************
  77. * EQUAL
  78. ***************************************/
  79. %}
  80. "=" {
  81. return EQUAL;
  82. }
  83. %{
  84. /***************************************
  85. * COMPARISON OPERATOR
  86. ***************************************/
  87. %}
  88. "<>" |
  89. "<" |
  90. ">" |
  91. "<=" |
  92. ">=" |
  93. "~" {
  94. yylval.strval = (char*)strdup(yytext);
  95. return COMPARISON_OPERATOR;
  96. }
  97. %{
  98. /***************************************
  99. * PUNCTUATION
  100. ***************************************/
  101. %}
  102. [-+*/:(),.;] {
  103. yylval.strval = (char*)strdup(yytext);
  104. return yytext[0];
  105. }
  106. %{
  107. /***************************************
  108. * NAMES
  109. ***************************************/
  110. %}
  111. [A-Za-z][A-Za-z0-9_]* {
  112. yylval.strval = (char*)strdup(yytext);
  113. return NAME;
  114. }
  115. %{
  116. /***************************************
  117. * INTEGER
  118. ***************************************/
  119. %}
  120. [0-9]+ {
  121. yylval.intval = atoi(yytext);
  122. /* yylval.strval = (char*)strdup(yytext); */
  123. return INTNUM;
  124. }
  125. %{
  126. /***************************************
  127. * FLOATING POINT NUM
  128. ***************************************/
  129. %}
  130. "."[0-9]* |
  131. [0-9]+"."[0-9]* |
  132. [0-9]+[eE][+-]?[0-9]+ |
  133. [0-9]+"."[0-9]*[eE][+-]?[0-9]+ |
  134. "."[0-9]*[eE][+-]?[0-9]+ {
  135. yylval.floatval = atof(yytext);
  136. /* yylval.strval = (char*)strdup(yytext); */
  137. return FLOATNUM;
  138. }
  139. %{
  140. /***************************************
  141. * STRINGS (single quotes)
  142. ***************************************/
  143. %}
  144. '[^']*' {
  145. char *Buffer, *ptra, *ptrb;
  146. int c = input();
  147. int len;
  148. Buffer = (char*)strdup(yytext); /* store here because we lose it when unput() */
  149. unput( c ); /* just peeking - checking for a double quote... embedded quote */
  150. if ( c != '\'' )
  151. {
  152. len = strlen (Buffer);
  153. Buffer[len-1] = '\0';
  154. /* Hopefully replace all '' by ' */
  155. ptrb = Buffer + 1;
  156. while ( (ptra = strchr(ptrb, '\'')) != NULL ) {
  157. ptra++; ptrb = ptra;
  158. while ( ptra[1] != 0 ) { ptra[0] = ptra[1]; ptra++; }
  159. ptra[0] = 0;
  160. }
  161. yylval.strval = (char*)strdup(Buffer+1);
  162. free( Buffer );
  163. return STRING;
  164. }
  165. else
  166. {
  167. free( Buffer );
  168. yymore();
  169. }
  170. }
  171. %{
  172. /***************************************
  173. * STRINGS (unterminated)
  174. ***************************************/
  175. %}
  176. '[^'\n]*$ { yyerror("Unterminated string"); }
  177. %{
  178. /***************************************
  179. * NEW LINE (ignored)
  180. ***************************************/
  181. %}
  182. \n ;
  183. %{
  184. /***************************************
  185. * WHITE SPACE (ignored)
  186. ***************************************/
  187. %}
  188. [ \t\r]+ ; /* white space */
  189. %{
  190. /***************************************
  191. * COMMENTS (ignored)
  192. ***************************************/
  193. %}
  194. "--".*$ ; /* comment */
  195. /***************************************
  196. * DEFAULT RULE
  197. ***************************************/
  198. . { yyerror("Syntax error"); }
  199. %%
  200. /**********************************************************************
  201. *
  202. * C-CODE
  203. *
  204. **********************************************************************/
  205. /**********************************************************************
  206. * my_yyinput
  207. *
  208. * Lexer will ask this function for input when it requires more.
  209. *
  210. **********************************************************************/
  211. int my_yyinput(char *buf, int max_size)
  212. {
  213. int rest, n;
  214. rest = sqlpStmt->stmt + strlen( sqlpStmt->stmt) - sqlpStmt->cur;
  215. n = ( max_size < rest ? max_size : rest );
  216. if ( n > 0 )
  217. {
  218. memcpy( buf, sqlpStmt->cur, n );
  219. sqlpStmt->cur += n;
  220. }
  221. return n;
  222. }
  223. /**********************************************************************
  224. * yyerror
  225. *
  226. * This should be called just before failing. It formats a meaningfull
  227. * message and deposits it in a usefull place.
  228. *
  229. **********************************************************************/
  230. void yyerror( char *s )
  231. {
  232. snprintf( sqlpStmt->errmsg, 500, "%s processing '%s'", s, yytext );
  233. #ifdef YY_CURRENT_BUFFER
  234. yy_flush_buffer(YY_CURRENT_BUFFER);
  235. #endif
  236. }
  237. /**********************************************************************
  238. * yywrap
  239. *
  240. * We are not doing any buffer switching but lets not use the Flex version of
  241. * of this func anyway so we can avoid the link dependency.
  242. *
  243. **********************************************************************/
  244. int yywrap()
  245. {
  246. return 1;
  247. }