%{
/*
* AT&T lex can't handle this lexer due to lex bugs. It works with flex
* 2.3.7, pclex 2.0.5, and MKS lex 3.1a.
*/
#include "sql1.h"
#include <string.h>
int lineno = 1;
void yyerror(char *s);
%}
/* MKS needs the next line to increase the NFA table */
%e 1200
%%
/* literal keyword tokens */
ADA { return ADA; }
ALL { return ALL; }
AND { return AND; }
AVG { return AMMSC; }
MIN { return AMMSC; }
MAX { return AMMSC; }
SUM { return AMMSC; }
COUNT { return AMMSC; }
ANY { return ANY; }
AS { return AS; }
ASC { return ASC; }
AUTHORIZATION { return AUTHORIZATION; }
BETWEEN { return BETWEEN; }
BY { return BY; }
C { return C; }
CHAR(ACTER)? { return CHARACTER; }
CHECK { return CHECK; }
CLOSE { return CLOSE; }
COBOL { return COBOL; }
COMMIT { return COMMIT; }
CONTINUE { return CONTINUE; }
CREATE { return CREATE; }
CURRENT { return CURRENT; }
CURSOR { return CURSOR; }
DECIMAL { return DECIMAL; }
DECLARE { return DECLARE; }
DEFAULT { return DEFAULT; }
DELETE { return DELETE; }
DESC { return DESC; }
DISTINCT { return DISTINCT; }
DOUBLE { return DOUBLE; }
ESCAPE { return ESCAPE; }
EXISTS { return EXISTS; }
FETCH { return FETCH; }
FLOAT { return FLOAT; }
FOR { return FOR; }
FOREIGN { return FOREIGN; }
FORTRAN { return FORTRAN; }
FOUND { return FOUND; }
FROM { return FROM; }
GO[ \t]*TO { return GOTO; }
GRANT { return GRANT; }
GROUP { return GROUP; }
HAVING { return HAVING; }
IN { return IN; }
INDICATOR { return INDICATOR; }
INSERT { return INSERT; }
INT(EGER)? { return INTEGER; }
INTO { return INTO; }
IS { return IS; }
KEY { return KEY; }
LANGUAGE { return LANGUAGE; }
LIKE { return LIKE; }
MODULE { return MODULE; }
NOT { return NOT; }
NULL { return NULLX; }
NUMERIC { return NUMERIC; }
OF { return OF; }
ON { return ON; }
OPEN { return OPEN; }
OPTION { return OPTION; }
OR { return OR; }
ORDER { return ORDER; }
PASCAL { return PASCAL; }
PLI { return PLI; }
PRECISION { return PRECISION; }
PRIMARY { return PRIMARY; }
PRIVILEGES { return PRIVILEGES; }
PROCEDURE { return PROCEDURE; }
PUBLIC { return PUBLIC; }
REAL { return REAL; }
REFERENCES { return REFERENCES; }
ROLLBACK { return ROLLBACK; }
SCHEMA { return SCHEMA; }
SELECT { return SELECT; }
SET { return SET; }
SMALLINT { return SMALLINT; }
SOME { return SOME; }
SQLCODE { return SQLCODE; }
TABLE { return TABLE; }
TO { return TO; }
UNION { return UNION; }
UNIQUE { return UNIQUE; }
UPDATE { return UPDATE; }
USER { return USER; }
VALUES { return VALUES; }
VIEW { return VIEW; }
WHENEVER { return WHENEVER; }
WHERE { return WHERE; }
WITH { return WITH; }
WORK { return WORK; }
/* punctuation */
"=" |
"<>" |
"<" |
">" |
"<=" |
">=" { return COMPARISON; }
[-+*/:(),.;] { return yytext[0]; }
/* names */
[A-Za-z][A-Za-z0-9_]* { return NAME; }
/* numbers */
[0-9]+ |
[0-9]+"."[0-9]* |
"."[0-9]* { return INTNUM; }
[0-9]+[eE][+-]?[0-9]+ |
[0-9]+"."[0-9]*[eE][+-]?[0-9]+ |
"."[0-9]*[eE][+-]?[0-9]+ { return APPROXNUM; }
/* strings */
'[^'\n]*' {
int c = input();
unput(c); /* just peeking */
if(c != '\'') {
return STRING;
} else
yymore();
}
'[^'\n]*$ { yyerror("Unterminated string"); }
\n lineno++;
[ \t\r]+ ; /* white space */
"--".*$ ; /* comment */
%%
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())
printf("SQL parse worked\n");
else
printf("SQL parse failed\n");
} /* main */