如何允许好的空间和禁止坏的精神
How to allow ok spaces and ban bad ones with boost spirit
励志例子
好:
SELECT a, b, c d,e FROM t1
坏:
SE L ECT a, b, c d,e FR OM t1
SELECTa, b, c d,eFROMt1
所以你可以看到这里的问题是有些空格是可以的(例如在SELECT和a,b,c之间),有些是不好的(SE LECT),有些是必要的(在关键字之后/之前)。
那么我的问题是这里应该使用什么习惯用法因为如果我将space
skipper与phrase_parse
一起使用它会允许坏的空格如果我想允许没有skipper的好空格解析器会被*char_(' ')
打乱
您需要将关键字标记为qi::lexeme[]
。
此外,您可能想要类似boost::spirit::repository::qi::distinct
的东西来避免将SELECT2
解析为SELECT
后面跟着2。
看到如。
- Boost spirit船长问题
- boost::spirit::qi关键字和标识符
您正在寻找的是解析。
这不是关于接受/拒绝"好"或"坏"的空间。它是关于尝试识别输入的内容,如果不能,则拒绝它。
在本例中,让我们从所讨论语句的(彻底简化的)语法开始:
select_statement ::= 'select' field_list 'from' table
那么,读入第一个令牌。如果是SE
或SELECTa
,则将该语句视为无效而拒绝,因为它们都不符合您的语法。几乎任何像样的解析器生成器(包括但肯定不限于Spirit)都使这相当简单——您指定是可接受的,以及如果输入不可接受该如何处理,并且它处理调用不符合指定语法的输入。
至于如何开始标记化,通常非常简单,通常可以基于正则表达式(例如,许多语言已经使用lex
和Flex等衍生语言实现,它们使用regexen来指定标记化)。
对于这样的东西,你直接为你的语言指定关键字,所以你会有一些东西说当它匹配'select'时,它应该返回那个作为一个标记。然后,您有一些更通用的标识符,通常运行类似于"[_a-zA-Z][_a-zA-Z0-9]*"("标识符以下划线或字母开头,后跟任意数量的下划线、字母或数字")。在上述情况下,这将完全足以找到并返回"SE"answers"SELECTa"作为"坏"示例中的第一个令牌。
解析器然后会检测到它接收到的第一个东西是标识符而不是关键字,此时它(可能)会被拒绝。
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 命名空间中具有.h和.cpp文件的类
- 从父命名空间重载类型
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 在命名空间中定义函数还是限定函数
- C++:对不存在的命名空间使用命名空间指令
- 通过继承类使用来自不同命名空间的运算符
- 使用命名空间时出现多个定义错误
- OpenGL相机和相机空间转型的困惑
- CUDA内核和数学函数的显式命名空间
- 打印第二列时的2d字符矢量打印空间
- 嵌套的匿名命名空间
- CMakeLists.txt中的命名空间表示法
- 类是C++中的命名空间吗
- 在命名空间中使用全局命名空间中的函数
- 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?
- '使用命名空间{嵌套在另一个命名空间中的某个命名空间}"
- 禁止 emacs 中的 c++ 命名空间缩进
- 如何允许好的空间和禁止坏的精神
- 为什么禁止同时打开多个命名空间