sqlp.l 7.1 KB

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