无法匹配 Alex 语法中的单个字符

发布于 2024-11-19 03:48:22 字数 1374 浏览 4 评论 0原文

我终于重新充实了一个 GitCommit 消息模式,我想将其添加到 YI 中,但我似乎缺少一些基本的东西。我似乎无法匹配语法中的单个字符,我的所有规则只有在匹配整行时才有效。我知道这必须是可能的,因为 YI 中的其他语法显然会这样做,但做同样的事情似乎不起作用。

我想要一种最终看起来与 vim 中的提交模式非常相似的提交模式。在 vim 模式中有用的事情之一是注释内的关键字突出显示。 Git 在它所做的几乎所有事情(提交、变基等)中都会在注释中放入大量信息,因此这很有用。我的想法是匹配 git 注释中的起始“#”字符,并切换到与关键字匹配的不同上下文。但是,我似乎无法制定仅匹配“#”的规则,该规则在“仅”包含“#”但在行上切换为注释样式包含“#”之后的任何内容,它不会切换样式。

我现在拥有的是:

<0> {
\#                             { m (const $ LineComment) Style.commentStyle }
$commitChars*$                 { c Style.defaultStyle }
}

<lineComment> {                                                                                                    
$nl                            { m (const Digest) Style.defaultStyle }                                               
·                              { c Style.regexStyle }                                                                
}      

细节明显省略。这个想法是当我们看到“#”时切换到“lineComment”模式,并以不同的方式设置样式,直到看到行尾。根据文档和示例,应该有一种方法可以做到我想要的。我已经尝试了几乎所有我能想到的“#”模式排列,但没有任何改变我所看到的行为。
我错过了什么明显的事情?

编辑: 上面的代码来自我的YI分支内部的实现。我有一个独立的解析器,此处也出现同样的问题。如果您运行 alex GitCommit.x && ghc --make GitCommit.hs && ./GitCommit < Shortmsg 您将看到内容解析为 MessageLine 的注释行以及正确标记为 CommentStart 的空注释行。

I finally got back to fleshing out a GitCommit message mode that I want to add to YI but I seem to missing something basic. I can't seem to match a single character in a grammar, all my rules only work if they match the entire line. I know this has to be possible because other grammars in YI obviously do this but doing the same thing doesn't seem to work.

I want to have a commit mode that eventually looks very similar to the one in vim. One of the things that's useful in vim's mode is the keyword highlighting inside comments. Git puts a bunch of information inside comments in most everything it does (commit, rebase, etc.) so this is useful. My thinking was match the starting '#' character in git comments and switch to a different context that will match keywords. However I can't seem to make a rule that matches just the '#', the rule switches to comment style on lines that only contain a '#' but on lines that contain anything after the '#' it does not switch styles.

What I have right now is:

<0> {
\#                             { m (const $ LineComment) Style.commentStyle }
$commitChars*$                 { c Style.defaultStyle }
}

<lineComment> {                                                                                                    
$nl                            { m (const Digest) Style.defaultStyle }                                               
·                              { c Style.regexStyle }                                                                
}      

Details omitted obviously. The idea is to switch to 'lineComment' mode when we see a '#' and style things differently until we see the end of the line. According to the documentation and examples there should be a way to do what I want. I've tried pretty much every permutation I can think of for the '#' pattern but nothing changes the behavior I'm seeing.
What obvious thing am I missing?

Edit:
The above code is from the implementation inside my YI branch. I have a standalone parser that exhibits the same problem here. If you run alex GitCommit.x && ghc --make GitCommit.hs && ./GitCommit < shortmsg you will see comment lines with content parsed as MessageLine and empty comment lines correctly marked CommentStart.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月如刀 2024-11-26 03:48:22

好吧,我终于明白了。看起来 Alex 总是选择最长的比赛,而不是第一场比赛。匹配提交行的规则总是会更长,因为它匹配整行。这会导致 Alex 始终选择该分支而不是评论分支。引用 Alex 文档


当输入流匹配多个规则时,匹配输入流最长前缀的规则获胜。如果仍有多个规则匹配相同数量的字符,则文件中最早出现的规则获胜。

我想我应该不止一次地阅读这些文档。解决方案是从 $commitChars 字符集中删除“#”。

Okay I finally figured this out. It looks like Alex always takes the longest match, not the first match. The rule for matching commit lines will always be longer since it matches the whole line. This causes Alex to always choose that branch over the comment branch. Quoting from the Alex docs


When the input stream matches more than one rule, the rule which matches the longest prefix of the input stream wins. If there are still several rules which match an equal number of characters, then the rule which appears earliest in the file wins.

I guess I should have read the docs more than once. The solution is to remove the '#' from the $commitChars character set.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文