%{
#include "sql2.h"
#include <string.h>
int lineno = 1;
void yyerror(char *s);
/* macro to save the text of a SQL token */
#define SV save_str(yytext)
/* macro to save the text and return a token */
#define TOK(name) { SV;return name; }
%}
%s SQL
%%
EXEC[ \t]+SQL { BEGIN SQL; start_save(); }
/* literal keyword tokens */
<SQL>ALL TOK(ALL)
<SQL>AND TOK(AND)
<SQL>AVG TOK(AMMSC)
<SQL>MIN TOK(AMMSC)
<SQL>MAX TOK(AMMSC)
<SQL>SUM TOK(AMMSC)
<SQL>COUNT TOK(AMMSC)
<SQL>ANY TOK(ANY)
<SQL>AS TOK(AS)
<SQL>ASC TOK(ASC)
<SQL>AUTHORIZATION TOK(AUTHORIZATION)
<SQL>BETWEEN TOK(BETWEEN)
<SQL>BY TOK(BY)
<SQL>CHAR(ACTER)? TOK(CHARACTER)
<SQL>CHECK TOK(CHECK)
<SQL>CLOSE TOK(CLOSE)
<SQL>COMMIT TOK(COMMIT)
<SQL>CONTINUE TOK(CONTINUE)
<SQL>CREATE TOK(CREATE)
<SQL>CURRENT TOK(CURRENT)
<SQL>CURSOR TOK(CURSOR)
<SQL>DECIMAL TOK(DECIMAL)
<SQL>DECLARE TOK(DECLARE)
<SQL>DEFAULT TOK(DEFAULT)
<SQL>DELETE TOK(DELETE)
<SQL>DESC TOK(DESC)
<SQL>DISTINCT TOK(DISTINCT)
<SQL>DOUBLE TOK(DOUBLE)
<SQL>ESCAPE TOK(ESCAPE)
<SQL>EXISTS TOK(EXISTS)
<SQL>FETCH TOK(FETCH)
<SQL>FLOAT TOK(FLOAT)
<SQL>FOR TOK(FOR)
<SQL>FOREIGN TOK(FOREIGN)
<SQL>FOUND TOK(FOUND)
<SQL>FROM TOK(FROM)
<SQL>GO[ \t]*TO TOK(GOTO)
<SQL>GRANT TOK(GRANT)
<SQL>GROUP TOK(GROUP)
<SQL>HAVING TOK(HAVING)
<SQL>IN TOK(IN)
<SQL>INDICATOR TOK(INDICATOR)
<SQL>INSERT TOK(INSERT)
<SQL>INT(EGER)? TOK(INTEGER)
<SQL>INTO TOK(INTO)
<SQL>IS TOK(IS)
<SQL>KEY TOK(KEY)
<SQL>LANGUAGE TOK(LANGUAGE)
<SQL>LIKE TOK(LIKE)
<SQL>NOT TOK(NOT)
<SQL>NULL TOK(NULLX)
<SQL>NUMERIC TOK(NUMERIC)
<SQL>OF TOK(OF)
<SQL>ON TOK(ON)
<SQL>OPEN TOK(OPEN)
<SQL>OPTION TOK(OPTION)
<SQL>OR TOK(OR)
<SQL>ORDER TOK(ORDER)
<SQL>PRECISION TOK(PRECISION)
<SQL>PRIMARY TOK(PRIMARY)
<SQL>PRIVILEGES TOK(PRIVILEGES)
<SQL>PROCEDURE TOK(PROCEDURE)
<SQL>PUBLIC TOK(PUBLIC)
<SQL>REAL TOK(REAL)
<SQL>REFERENCES TOK(REFERENCES)
<SQL>ROLLBACK TOK(ROLLBACK)
<SQL>SCHEMA TOK(SCHEMA)
<SQL>SELECT TOK(SELECT)
<SQL>SET TOK(SET)
<SQL>SMALLINT TOK(SMALLINT)
<SQL>SOME TOK(SOME)
<SQL>SQLCODE TOK(SQLCODE)
<SQL>TABLE TOK(TABLE)
<SQL>TO TOK(TO)
<SQL>UNION TOK(UNION)
<SQL>UNIQUE TOK(UNIQUE)
<SQL>UPDATE TOK(UPDATE)
<SQL>USER TOK(USER)
<SQL>VALUES TOK(VALUES)
<SQL>VIEW TOK(VIEW)
<SQL>WHENEVER TOK(WHENEVER)
<SQL>WHERE TOK(WHERE)
<SQL>WITH TOK(WITH)
<SQL>WORK TOK(WORK)
/* punctuation */
<SQL>"=" |
<SQL>"<>" |
<SQL>"<" |
<SQL>">" |
<SQL>"<=" |
<SQL>">=" TOK(COMPARISON)
<SQL>[-+*/(),.;] TOK(yytext[0])
/* names */
<SQL>[A-Za-z][A-Za-z0-9_]* TOK(NAME)
/* parameters */
<SQL>":"[A-Za-z][A-Za-z0-9_]* {
save_param(yytext+1);
return PARAMETER;
}
/* numbers */
<SQL>[0-9]+ |
<SQL>[0-9]+"."[0-9]* |
<SQL>"."[0-9]* TOK(INTNUM)
<SQL>[0-9]+[eE][+-]?[0-9]+ |
<SQL>[0-9]+"."[0-9]*[eE][+-]?[0-9]+ |
<SQL>"."[0-9]*[eE][+-]?[0-9]+ TOK(APPROXNUM)
/* strings */
<SQL>'[^'\n]*' {
int c = input();
unput(c); /* just peeking */
if(c != '\'') {
SV;return STRING;
} else
yymore();
}
<SQL>'[^'\n]*$ { yyerror("Unterminated string"); }
<SQL>\n { save_str(" ");lineno++; }
\n { lineno++; ECHO; }
<SQL>[ \t\r]+ save_str(" "); /* white space */
<SQL>"--".* ; /* comment */
ECHO; /* random non-SQL text */
%%
void
yyerror(char *s)
{
printf("%d: %s at %s\n", lineno, s, yytext);
}
main(int ac, char **av)
{
if(ac > 1 && (yyin = fopen(av[1], "r")) == NULL) {
perror(av[1]);
exit(1);
}
if(!yyparse())
fprintf(stderr, "Embedded SQL parse worked\n");
else
fprintf(stderr, "Embedded SQL parse failed\n");
} /* main */
/* leave SQL lexing mode */
un_sql()
{
BEGIN INITIAL;
} /* un_sql */