> For the complete documentation index, see [llms.txt](https://decaf-lang.gitbook.io/decaf-book/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://decaf-lang.gitbook.io/decaf-book/rust-kuang-jia-fen-jie-duan-zhi-dao/pa1a-yu-fa-fen-xi-qi-de-zi-dong-gou-zao/lalr1-shi-yong-zhi-dao/impl-kuai-de-ke-xuan-shu-xing.md).

# impl块的可选属性

除了`#[lalr1(Start)]`和`#[lex(TomlOfLexer)]`这两个必要的属性外，还可以添加几个额外的属性，目前支持的有以下几个：

1. `#[verbose(OutputPath)]`

   把lalr(1)的action表打印到文件`OutputPath`，出现冲突警告的时候可以利用这个文件来帮助查找语法中的问题。

   action表中包含每个节点包含的产生式及点的位置(不包含向前看符号)，以及每个节点处遇到终结符时的移进/规约/接受动作。每个动作都会在后面加上一个表示冲突情况的符号，示例如下：

   ```
    A => Shift(1) (✓)
    A => Reduce(1) (-)
    B => Shift(2) (✓)
    B => Reduce(2) (✗)
   ```

   其中`(✓)`表示它最后被解析器采用，`(-)`表示它被利用优先级和结合性消除了，`(✗)`表示它被"强行"消除了，对应与一个冲突警告。详见后面的解决冲突一节。

   如果选择了ll(1)来生成parser，则会打印ll(1)的预测集合(predict set)，同样`(✗)`表示一个产生式被"强行"消除了，而因为ll(1)中没有利用优先级和结合性来消除冲突的机制，所以不存在`(-)`。
2. `#[log_token]`

   每当新解析出一个非`_Eps`的终结符时，输出它的相关信息，也就是输出一个struct `Token`，包括名字，对应源代码，行号列号。
3. `#[log_reduce]`

   每当执行一次规约时，输出产生式。
4. `#[use_unsafe]`

   使用一些`unsafe`来减少运行时检查，以期提高性能。例如将不可达断言转化成不可达hint，取消下标越界检查等。

   如果你编写的parser是正确的，那么无论输入的程序是是什么，这些`unsafe`都不会导致真正不安全的结果(至少lalr1的目标是这个，至于是否真的达到了，目前暂且不能做出保证)。
5. `#[expand]`

   会在编译时输出生成的代码。之所以添加这个选项而不建议大家使用`cargo expand`来查看生成的代码，是因为后者把所有宏都展开了，不利于阅读或者调试，而且后者要求rustc的编译至少成功进行到了某个阶段(具体哪个阶段我还不清楚)才会输出，这对帮助解决编译错误可能是没有帮助的。

   由于lalr1生成的rust代码不包含位置信息，**所以parser中的编译错误和运行错误都无法得知具体在什么位置**，而如果使用`#[expand]`输出的代码来代替整个impl块，效果是完全等同的，这样可以方便调试或者看自己具体那里编译出错了。
6. `#[show_fsm(OutputPath)]`和`#[show_dfa(OutputPath)]`

   分别是把parser的lr fsm和lexer的dfa的图形以dot文件的形式输出到对应路径中。其实是没啥用的一个功能，因为这两个自动机都太大了，甚至dot文件都不一定能顺利地渲染成图片，更不用说靠人眼从中提取什么有用的信息了。这两个选项可以说纯属娱乐，如果电脑性能比较好的话不妨尝试一下看看自动机到底长啥样。

   不过这个功能也并不是完全没用的，re2dfa和lalr1中都提供了生成dot文件的接口，如果是一些简单一点的例子，的确是可以用来输出有意义的图片的\~\~(例如作业题什么的)\~\~。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://decaf-lang.gitbook.io/decaf-book/rust-kuang-jia-fen-jie-duan-zhi-dao/pa1a-yu-fa-fen-xi-qi-de-zi-dong-gou-zao/lalr1-shi-yong-zhi-dao/impl-kuai-de-ke-xuan-shu-xing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
