2

我已经找了两个小时了,我真的不知道该怎么办。

我正在尝试构建一个分析器,它使用可以匹配几千个单词的词法分析器。这些是自然语言单词,这就是为什么它们如此之多。

我首先以一种简单的方式尝试了一个令牌只有 1000 个不同的匹配项:

    TOKEN :
{
    <VIRG: ",">
|   <COORD: "et">
|   <ADVERBE: "vraiment">
|   <DET: "la">
|   <ADJECTIF: "bonne">
|   <NOM: "pomme"
        |   "émails"
        |   "émaux"
        |   "APL"
        |   "APLs"
        |   "Acide"
        |   "Acides"
        |   "Inuk"

[...]

javac编译后返回代码太大。

那么,如何在我的 lexer 中管理数千个令牌?

  1. 我已经读过,对每个单词使用 n 个标记比对 n 个单词使用一个标记更有效。但在这种情况下,我将有 1000 多个令牌的规则,这看起来不是一个更好的主意;

  2. 我可以修改令牌管理器,或者构建一个,所以它只匹配列表中的单词;

  3. 在这里我知道词法分析器是一个有限状态机,这就是为什么它不可能,所以无论如何要使用其他词法分析器?;

  4. 我可以自动生成一个匹配每个单词的巨大正则表达式,但这不会让我之后独立处理这些单词,而且我不确定编写一个 60 行正则表达式是否是个好主意;

  5. 也许有办法从文件中加载令牌,这个解决方案非常接近解决方案 2 和 3;

  6. 也许我应该使用另一种语言?我正在尝试从 XLE(可以处理超过 70 000 个令牌的词典)迁移到 java,这里有趣的是生成 java 文件!

所以在这里,我可以找到使用 javacc 词法分析器处理数千个标记的方法。如果有人习惯并有想法,那就太好了?

最好的

科伦廷

4

1 回答 1

3

我不知道 javacc 是如何构建它的 DFA 的,但可以肯定的是,能够区分数千个单词的 DFA 会非常大。(但绝不是不合理的大:我已经灵活地构建了具有数十万个州的 DFA,而没有出现重大问题。)

具有大量固定词位的词典的常用方法是使用 DFA 识别潜在单词(例如,字母字符序列),然后在字典中查找单词以获取标记类型。这也更加灵活,因为您可以在不重新编译的情况下更新字典。

于 2016-11-16T19:55:31.250 回答