之前那篇博文Mini SQL 总体设计(一) 中在提到Tokens分割的时候试图进行句法分析,这个问题就相当复杂了。
看了指针1 实现的Token分割之后,我发现我有个地方搞错了。我试图将SQL语句中充当不同成分的部分提取出来,就像分析主谓宾一样,这实际上是句法分析。对于正则表达式来说未免任务过重。
而且JS正则表达式不具有平衡组,也无法进行无限深度的括号平衡匹配。
应该把Tokens分割地更细,然后将逻辑复杂度转移到Token分割之后的Router里。
其实问题应该是很简单的:
/\w+|[^\s]/g
用这个正则去匹配SQL语句就可以了。
除了要匹配正常的字符串\w+
,还要保留除了空白字符\s
之外的各种符号:如括号\(
\)
、逗号,
、引号'
"
等号=
、以及分号;
等等;
保留除了空白符的部分来提示之后的路由分配,保证信息无损传递。
tokenizer = (sql) => sql.match(/\w+|[^\s]/g);
tokenizer('create table t(a int, b varchar(20));'); // ["create", "table", "t", "(", "a", "int", ",", "b", "varchar",