提交 0ecfca2b 编写于 作者: S senllang

toadb scanner and gram paser init

上级 b0820509
# Makefile toadb project
# create by senllang 2021/1/1
# mail : study@senllang.onaliyun.com
# Copyright (C) 2023-2023, senllang
#
VERSION_H = 0
VERSION_L = 01
TARGET = toadb-${VERSION_H}-${VERSION_L}
##########################################
# toplevel source code directory
# topdir=$(shell pwd)
topdir = .
SRC_DIR=$(topdir)
# search all directory and subdirectory
DIRS = $(shell find $(SRC_DIR) -maxdepth 5 -type d)
# general source file list , and objects list
SOURCE = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
OBJS = ${patsubst %.c, %.o, $(SOURCE)}
# .h files take place all directories.
INC = ${foreach dir, $(DIRS), -I$(dir)}
SCANNER = scanner.c
PARSER = grammar.c
PARSER_H = grammar.h
##########################################
# test programme
builddir = $(topdir)/build
##########################################
##########################################
DEFINES += -DTEST_PRO
LDFLAGS += -lpthread
DEBUG_FLAGS = -g
##########################################
CC = gcc
#CFLAGS += -O2
CFLAGS += ${INC}
CFLAGS += ${DEFINES}
CFLAGS += ${LDFLAGS}
CFLAGS += ${DEBUG_FLAGS}
# compile start
.PHONY: all clean
all: $(default) $(builddir) $(OBJS) $(TARGET)
#build dir create
$(builddir):
mkdir -p $(builddir)
# object compile to O_PATH
.c.o: $(SOURCE)
$(CC) $(CFLAGS) -c $<
$(TARGET):$(topdir)/*.o
$(CC) $(CFLAGS) $^ -o $@
# show various value
default:
echo -e $(DIRS)
echo -e $(SOURCE)
echo -e $(OBJS)
echo -e $(INC)
parser: $(PARSER) $(SCANNER)
$(PARSER): $(topdir)/grammar.y
bison --defines=${PARSER_H} -o $@ $<
$(SCANNER): $(topdir)/scanner.l
flex -o $@ $<
clean:
rm -rf ${TARGET} ${OBJS} ${builddir} $(topdir)/*.o ${SCANNER} ${PARSER} ${PARSER_H}
### Cluster management template project
# 数据库SQL解析
分为两部分,
词法分析器scanner
语法分析器grammar
Example [cluster management](https://docs.gitlab.com/ee/user/clusters/management_project.html) project.
## 目前支持的SQL情况:
支持DDL:
create table name (column type,..);
drop table name;
This project is based on a GitLab [Project Template](https://docs.gitlab.com/ee/gitlab-basics/create-project.html).
支持DML:
select */ column, ... from tablename;
insert into tablename(column,...) values(columnvalue,...);
Improvements can be proposed in the [original project](https://gitlab.com/gitlab-org/project-templates/cluster-management).
## 开发指南
词法分析器和语法分析器使用了著名的开源工具flex和bison组合,flex能够按照正则表达式规则解析出关键字,标识符,以及其它字符串;而bison则通过它的语法推导规则,将各个部分解析成一个个表达式,每个表达式形成逆波兰式的抽象语法树。
### 词法分析器编写过程的注意事项:
词法分析器是向前看一个字符,所以对于规则在文件中的前后顺序就有要求。比如标识符字串如果放在操作符规则之后,那么在匹配时就会先匹配到操作符的分号,此时就会执行操作符的规则,而把前面的字符串会丢掉,把两者换个顺序就会优先匹配标识符,当下一个字符为分号时,先执行标识符的动作,再取分号进行分析。
### 语法分析器编写过程注意事项:
语法分析器在编写过程中遇到两个问题:
(1)语法分析器规则里要使用当前表达式的值时,需要给表达式定义类型,默认是yylval为整型,如果是字符串时,就需通过%union定义,然后在token里绑定类型;
(2)语法分析器第二部分规则定义部分,规则推导出的内容必须是词法分析器返回的内容,比如列名和类型中间是空格,但是空格在词法分析器中已经过滤掉了,就不能用空格来分隔了。
# 数据库SQL执行
# roadmap
## 0.1版本开发
功能:支持创建表,删除表,插入数据,删除数据
数据库特性:客户端,词法/语法解析,SQL执行,数据字典,存储管理
\ No newline at end of file
%{
/*
* toadb grammar
* Copyright (C) 2023-2023, senllang
*/
#include <stdio.h>
#include <stdlib.h>
int grammar_main();
%}
%union {
char *sval;
char op;
}
/* tokens define */
%token SELECT
%token CREATE
%token TABLE
%token FROM
%token DELETE
%token DROP
%token INSERT
%token UPDATE
%token <sval> IDENT
%%
stmt_list: ;
|stmt ';'
| stmt_list stmt ';'
;
stmt: select_stmt
{
printf("select stmt\n");
}
| create_stmt
{
printf("create stmt\n");
}
| drop_stmt
{
printf("drop stmt\n");
}
;
select_stmt: SELECT select_opt_list
{
printf("select \n");
}
| SELECT select_opt_list FROM table_reference_list
{
printf("select from \n");
}
;
select_opt_list: attr_name
| select_opt_list ',' attr_name
| '*'
;
table_reference_list: table_reference
| table_reference ',' table_reference
;
table_reference: IDENT
{
printf("list ident :%s\n", $1);
}
;
create_stmt: CREATE TABLE tablename '(' column_list ')'
{
printf("sql: create \n");
}
;
drop_stmt: DROP TABLE tablename
{
printf("sql drop \n");
}
;
tablename: IDENT
{
printf("ident :%s\n", $1);
}
;
column_list: attr_define
| column_list ',' attr_define
;
attr_define: attr_name attr_type
{
printf("attrdef \n");
}
;
attr_name: IDENT
{
printf("ident :%s\n", $1);
}
;
attr_type: IDENT
{
printf("ident :%s\n", $1);
}
;
%%
int grammar_main()
{
yyparse();
return 0;
}
yyerror(char *s)
{
fprintf(stderr, "error: %s\n",s);
}
/*
* toadb main
* Copyright (C) 2023-2023, senllang
*/
#include <stdio.h>
#include <stdlib.h>
#include "grammar.h"
int grammar_main();
int main(int argc, char *agrv[])
{
grammar_main();
return 0;
}
%top{
/*
* toadb scanner
* Copyright (C) 2023-2023, senllang
*/
}
/* define list */
%{
#include <stdio.h>
#include <stdlib.h>
#include "grammar.h"
int test = 0;
%}
%option outfile="scanner.c"
%option noyywrap
%option yylineno
%option case-insensitive
/* operators */
operator [-+&~|^/%*().!,;]
space [ \t\n\r\f]
nonewline [^\n\r]
comment ("--"{nonewline}*)
whitespace ({space}+|{comment})
identify [a-zA-Z][a-zA-Z0-9_]*
%%
SELECT {
return SELECT;
}
FROM {
return FROM;
}
CREATE {
return CREATE;
}
TABLE {
return TABLE;
}
UPDATE {
return UPDATE;
}
INSERT {
return INSERT;
}
DELETE {
return DELETE;
}
DROP {
return DROP;
}
{identify} {
yylval.sval = strdup(yytext);
return IDENT;
}
{operator} {
return yytext[0];
}
{whitespace} {
/* ignore */
}
%%
%top{
/*
* toadb scanner
* Copyright (C) 2023-2023, senllang
*/
}
/* define list */
%{
#include <stdio.h>
#include <stdlib.h>
int test = 0;
%}
%option outfile="scanner-test.c"
%option noyywrap
%option yylineno
%option case-insensitive
/* operators */
endtag [;]*
seperate [,]
operator [-+&~|^/%*().!]
space [ \t\n\r\f]
nonewline [^\n\r]
comment ("--"{nonewline}*)
whitespace ({space}+|{comment})
identify [a-zA-Z][a-zA-Z0-9_]*
%%
select {
printf("--select \n");
}
from {
printf("--from \n");
}
create {
printf("--CREATE\n");
}
update {
printf("--update\n");
}
insert {
printf("--insert\n");
}
delete {
printf("--delete\n");
}
drop {
printf("--drop\n");
}
{identify} {
printf("ident :%s\n", yytext);
}
{operator} {
printf("op:%c\n",yytext[0]);
}
{endtag} {
printf("end:%c\n",yytext[0]);
}
{seperate} {
printf("se:%c\n",yytext[0]);
}
{space} {
/* ignore */
}
{whitespace} {
/* ignore */
}
%%
int main(int argc, char * argv[])
{
/* | drop_stmt
{
printf("drop stmt\n");
}
| insert_stmt
{
printf("insert stmt\n");
}
| delete_stmt
{
printf("delete stmt\n");
}
*/
yylex();
return 0;
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册