added location tracking to parser
This commit is contained in:
parent
bda8db57e4
commit
98c84abcba
|
@ -57,6 +57,8 @@ public:
|
|||
|
||||
bool isValid;
|
||||
const char* parser_msg;
|
||||
int error_line;
|
||||
int error_col;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -19,13 +19,15 @@
|
|||
|
||||
using namespace hsql;
|
||||
|
||||
int yyerror(SQLStatementList** result, yyscan_t scanner, const char *msg) {
|
||||
int yyerror(YYLTYPE* llocp, SQLStatementList** result, yyscan_t scanner, const char *msg) {
|
||||
|
||||
SQLStatementList* list = new SQLStatementList();
|
||||
list->isValid = false;
|
||||
list->parser_msg = strdup(msg);
|
||||
*result = list;
|
||||
list->error_line = llocp->first_line;
|
||||
list->error_col = llocp->first_column;
|
||||
|
||||
*result = list;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -47,6 +49,8 @@ int yyerror(SQLStatementList** result, yyscan_t scanner, const char *msg) {
|
|||
%define api.token.prefix {SQL_}
|
||||
|
||||
%define parse.error verbose
|
||||
%locations
|
||||
|
||||
|
||||
// Specify code that is included in the generated .h and .c files
|
||||
%code requires {
|
||||
|
@ -57,6 +61,21 @@ typedef void* yyscan_t;
|
|||
#endif
|
||||
|
||||
#define YYSTYPE HSQL_STYPE
|
||||
#define YYLTYPE HSQL_LTYPE
|
||||
|
||||
|
||||
#define YY_USER_ACTION \
|
||||
yylloc->first_line = yylloc->last_line; \
|
||||
yylloc->first_column = yylloc->last_column; \
|
||||
for(int i = 0; yytext[i] != '\0'; i++) { \
|
||||
if(yytext[i] == '\n') { \
|
||||
yylloc->last_line++; \
|
||||
yylloc->last_column = 0; \
|
||||
} \
|
||||
else { \
|
||||
yylloc->last_column++; \
|
||||
} \
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -114,26 +133,27 @@ typedef void* yyscan_t;
|
|||
%token <uval> NOTEQUALS LESSEQ GREATEREQ
|
||||
|
||||
/* SQL Keywords */
|
||||
%token PARAMETERS INTERSECT TEMPORARY TIMESTAMP DISTINCT
|
||||
%token NVARCHAR RESTRICT TRUNCATE ANALYZE BETWEEN CASCADE
|
||||
%token COLUMNS CONTROL DEFAULT EXPLAIN HISTORY INTEGER
|
||||
%token NATURAL PRIMARY SCHEMAS SPATIAL VIRTUAL BEFORE COLUMN
|
||||
%token CREATE DELETE DIRECT DOUBLE ESCAPE EXCEPT EXISTS
|
||||
%token GLOBAL HAVING IMPORT INSERT ISNULL OFFSET RENAME
|
||||
%token SCHEMA SELECT SORTED TABLES UNIQUE UNLOAD UPDATE
|
||||
%token VALUES AFTER ALTER CROSS DELTA GROUP INDEX INNER
|
||||
%token LIMIT LOCAL MERGE MINUS ORDER OUTER RIGHT TABLE UNION
|
||||
%token USING WHERE CALL DATE DESC DROP FILE FROM FULL HASH
|
||||
%token INTO JOIN LEFT LIKE LOAD NULL PART PLAN SHOW TEXT
|
||||
%token TIME VIEW WITH ADD ALL AND ASC CSV FOR INT KEY NOT OFF
|
||||
%token SET TBL TOP AS BY IF IN IS OF ON OR TO
|
||||
%token DEALLOCATE PARAMETERS INTERSECT TEMPORARY TIMESTAMP
|
||||
%token DISTINCT NVARCHAR RESTRICT TRUNCATE ANALYZE BETWEEN
|
||||
%token CASCADE COLUMNS CONTROL DEFAULT EXECUTE EXPLAIN
|
||||
%token HISTORY INTEGER NATURAL PREPARE PRIMARY SCHEMAS
|
||||
%token SPATIAL VIRTUAL BEFORE COLUMN CREATE DELETE DIRECT
|
||||
%token DOUBLE ESCAPE EXCEPT EXISTS GLOBAL HAVING IMPORT
|
||||
%token INSERT ISNULL OFFSET RENAME SCHEMA SELECT SORTED
|
||||
%token TABLES UNIQUE UNLOAD UPDATE VALUES AFTER ALTER CROSS
|
||||
%token DELTA GROUP INDEX INNER LIMIT LOCAL MERGE MINUS ORDER
|
||||
%token OUTER RIGHT TABLE UNION USING WHERE CALL DATE DESC
|
||||
%token DROP FILE FROM FULL HASH HINT INTO JOIN LEFT LIKE
|
||||
%token LOAD NULL PART PLAN SHOW TEXT TIME VIEW WITH ADD ALL
|
||||
%token AND ASC CSV FOR INT KEY NOT OFF SET TBL TOP AS BY IF
|
||||
%token IN IS OF ON OR TO
|
||||
|
||||
|
||||
/*********************************
|
||||
** Non-Terminal types (http://www.gnu.org/software/bison/manual/html_node/Type-Decl.html)
|
||||
*********************************/
|
||||
%type <stmt_list> statement_list
|
||||
%type <statement> statement
|
||||
%type <statement> statement preparable_statement prepare_statement
|
||||
%type <select_stmt> select_statement select_with_paren select_no_paren select_clause
|
||||
%type <import_stmt> import_statement
|
||||
%type <create_stmt> create_statement
|
||||
|
@ -200,6 +220,12 @@ statement_list:
|
|||
;
|
||||
|
||||
statement:
|
||||
preparable_statement
|
||||
| prepare_statement
|
||||
;
|
||||
|
||||
|
||||
preparable_statement:
|
||||
select_statement { $$ = $1; }
|
||||
| import_statement { $$ = $1; }
|
||||
| create_statement { $$ = $1; }
|
||||
|
@ -211,6 +237,14 @@ statement:
|
|||
;
|
||||
|
||||
|
||||
/******************************
|
||||
* Prepared Statement
|
||||
******************************/
|
||||
prepare_statement:
|
||||
PREPARE IDENTIFIER ':' preparable_statement { $$ = NULL; }
|
||||
;
|
||||
|
||||
|
||||
|
||||
/******************************
|
||||
* Import Statement
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
%option warn
|
||||
%option case-insensitive
|
||||
%option prefix="hsql_"
|
||||
%option bison-locations
|
||||
/* %option nodefault */
|
||||
|
||||
|
||||
|
@ -58,6 +59,7 @@
|
|||
|
||||
|
||||
|
||||
DEALLOCATE TOKEN(DEALLOCATE)
|
||||
PARAMETERS TOKEN(PARAMETERS)
|
||||
INTERSECT TOKEN(INTERSECT)
|
||||
TEMPORARY TOKEN(TEMPORARY)
|
||||
|
@ -72,10 +74,12 @@ CASCADE TOKEN(CASCADE)
|
|||
COLUMNS TOKEN(COLUMNS)
|
||||
CONTROL TOKEN(CONTROL)
|
||||
DEFAULT TOKEN(DEFAULT)
|
||||
EXECUTE TOKEN(EXECUTE)
|
||||
EXPLAIN TOKEN(EXPLAIN)
|
||||
HISTORY TOKEN(HISTORY)
|
||||
INTEGER TOKEN(INTEGER)
|
||||
NATURAL TOKEN(NATURAL)
|
||||
PREPARE TOKEN(PREPARE)
|
||||
PRIMARY TOKEN(PRIMARY)
|
||||
SCHEMAS TOKEN(SCHEMAS)
|
||||
SPATIAL TOKEN(SPATIAL)
|
||||
|
@ -130,6 +134,7 @@ FILE TOKEN(FILE)
|
|||
FROM TOKEN(FROM)
|
||||
FULL TOKEN(FULL)
|
||||
HASH TOKEN(HASH)
|
||||
HINT TOKEN(HINT)
|
||||
INTO TOKEN(INTO)
|
||||
JOIN TOKEN(JOIN)
|
||||
LEFT TOKEN(LEFT)
|
||||
|
@ -172,7 +177,7 @@ TO TOKEN(TO)
|
|||
">=" TOKEN(GREATEREQ)
|
||||
|
||||
|
||||
[-+*/(),.;<>=^%] { return yytext[0]; }
|
||||
[-+*/(),.;<>=^%:?] { return yytext[0]; }
|
||||
|
||||
|
||||
[0-9]+"."[0-9]* |
|
||||
|
@ -204,7 +209,7 @@ TO TOKEN(TO)
|
|||
return SQL_STRING;
|
||||
}
|
||||
|
||||
|
||||
. { fprintf(stderr, "[SQL-Lexer-Error] Unknown Character: %c\n", yytext[0]); return 0; }
|
||||
|
||||
|
||||
%%
|
||||
|
@ -213,5 +218,5 @@ TO TOKEN(TO)
|
|||
***************************/
|
||||
|
||||
int yyerror(const char *msg) {
|
||||
fprintf(stderr, "[Error] SQL Lexer: %s\n",msg); return 0;
|
||||
fprintf(stderr, "[SQL-Lexer-Error] %s\n",msg); return 0;
|
||||
}
|
|
@ -101,6 +101,11 @@ UNLOAD
|
|||
|
||||
DELETE
|
||||
|
||||
// Prepared Statements
|
||||
DEALLOCATE
|
||||
PREPARE
|
||||
EXECUTE
|
||||
|
||||
///////////////////////////////
|
||||
// other statements
|
||||
RENAME
|
||||
|
@ -138,6 +143,7 @@ ESCAPE
|
|||
|
||||
// With
|
||||
WITH
|
||||
HINT
|
||||
PARAMETERS
|
||||
ON
|
||||
OFF
|
||||
|
|
|
@ -76,7 +76,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
if (expect_false == stmt_list->isValid) {
|
||||
printf("\033[0;31m{ failed}\033[0m\n");
|
||||
printf("\t\033[0;31m%s\n\033[0m", stmt_list->parser_msg);
|
||||
printf("\t\033[0;31m%s (L%d:%d)\n\033[0m", stmt_list->parser_msg, stmt_list->error_line, stmt_list->error_col);
|
||||
printf("\t%s\n", sql.c_str());
|
||||
num_failed++;
|
||||
} else {
|
||||
|
|
|
@ -30,3 +30,6 @@ UPDATE students SET grade = 1.3, name='Felix Fürstenberg' WHERE name = 'Max Mus
|
|||
UPDATE students SET grade = 1.0;
|
||||
# DROP
|
||||
DROP TABLE students;
|
||||
# PREPARE
|
||||
PREPARE prep_inst: INSERT INTO test VALUES (?, ?, ?); SELECT * FROM test;
|
||||
EXECUTE prep_inst(1, 2, 3);
|
Loading…
Reference in New Issue