提问人:Matrix22 提问时间:9/10/2023 最后编辑:user2722968Matrix22 更新时间:9/10/2023 访问量:44
Lexical Analyzer,具有表格驱动和字符分类功能
Lexical Analyzer with table-driven and character classification in rust
问:
我正在为 C 语言编写词法分析器作为 Rust 的练习,现在我成功地使用回溯实现了词法分析器,如下所示:
lex_keyword(input)
.or_else(|| lex_identifier(input))
.or_else(|| lex_integer(input))
...
.unwrap_or(lex_unexpected(input));
这按预期工作,但是它有点慢,因为它会尝试所有可能的解决方案,直到找到一个解决方案,并且每lex_function检查整个输入是否有效,然后尝试映射到令牌,例如在标识符上:
let end = input.iter().position(|byte| byte.is_ascii_whitespace() || /* is a punctuator */).unwrap_or(input.len());
// And then
if input[..end].iter().all(|byte| /* is valid identifier member */) { /* Return an identifer */ } else { None }
我已经阅读了有关词法分析器生成器如何实现词法分析器的信息。
因此,他们基本上将语法转换为 NFA,然后转换为 DFA,并执行主循环(这在理论上是好的)。
我读过关于 lex、flex 和 yacc 的文章,并且看到它们不仅为 DFA 生成一个查找表,而是生成一堆查找表,并且还使用字符类。而且,如果你要实现一个 DFA,他们的查找表也不是那么大,其中一行(state)将有 128 列(ASCII 字符)。
我的问题是,如何实现字符类,以及如何在 DFA 的查找表中使用它们,或者我可以为不同的规则创建不同的查找表,例如:
token ::=
keyword
| identifeer
| integer_literal
| float_literal
| ...
DFA_FOR_KEYWORD = [...]
DFA_FOR_IDENTIFIER = [...]
DFA_FOR_INTEGER = [...]
DFA_FOR_FLOAT = [...]
LEXER_DFA = [/* Which connects all the DFAs */]
还有关于character_classes,它们是如何编码的,你能为不同的部分重用同一个类吗?
例如:
假设标识符必须以字母“p”结尾
identifer ::= [a-zA-Z]*p
我会上多少节课?
- 一个用于 a-z,一个用于 A-Z,一个用于“p”
- 一个用于 a-zA-Z,一个用于“p”
- 一个用于 a-zA-Z,并检查它是否以“p”结尾
另一个问题是,如何在主循环中组装它们?
给定转换表,给定字符类和最后一个状态,您现在如何进行下一个转换(换句话说,如何编纂转换表以根据字符类移动)?
我 https://www.cs.man.ac.uk/%5C~pjj/cs211/ho/node6.html 查找此链接,但无法理解字符类的使用位置或它们的编码方式。
另外,如果您有关于此问题的一些资源,请随时分享
非常感谢您的建议
PS:我知道词法生成器可以完成所有这些事情,但是我想手动实现它作为练习的一部分。
答: 暂无答案
评论
rust