Java 使TreeSetter与类名匹配

Java 使TreeSetter与类名匹配,java,parsing,clojure,treesitter,Java,Parsing,Clojure,Treesitter,我正在使用解析Clojure代码。具体来说,我想区分符号、类名和 这是我的语法: module.exports = grammar({ name: 'clojure', extras: $ => [/[\s,]/], rules: { program: $ => repeat($._anything), _anything: $ => choice($.symbol, $.classname, $.member_acces

我正在使用解析Clojure代码。具体来说,我想区分符号、类名和

这是我的语法:

module.exports = grammar({
    name: 'clojure',
    extras: $ => [/[\s,]/],
    rules: {
        program: $ => repeat($._anything),
        _anything: $ => choice($.symbol, $.classname, $.member_access, $.new_class),

        symbol: $ => $._symbol_chars,

        classname: $ => prec.left(3, seq($._symbol_chars, repeat1($._classname_part ))),
        _classname_part: $ => prec.right(3, seq($._dot, $._symbol_chars)),

        member_access: $ => seq($._dot, $._class_chars),
        new_class: $ => prec(2, seq( choice($.symbol, $.classname), $._dot)),

        _dot: $ => /\.{1}/,
        _symbol_chars: $ =>   /[a-zA-Z\*\+\!\-_\?][\w\*\+\!\-\?\':]*/,
        _class_chars: $ => /[a-zA-Z_]\w*/
    }
})

我希望

foo
java.lang.String
.toUpperCase
java.awt.Point.
解析为

(program (
    (symbol)
    (classname)
    (member_access)
    (new_class (classname)))

但是Treesitter一直在查看
(新类(类名))(类名)
,而不是
(类名)
(Java.lang.String)。我想我需要某种贪婪的匹配,并且在不同的地方尝试了
prec.right()
,但没有成功。我遗漏了什么?

我是一个新手,所以请在处理以下内容时考虑到这一点:)

extras
包含此语法的空白。IIUC,这意味着如果在
seq
周围不适当地使用
token
,树管理员将尝试解释
seq
中项目之间可能出现空白的情况

例如:

seq($._dot, $._class_chars)
树管理员将尝试将“
$”和“
$”字符用空格分隔,视为有效。但IIUC在Clojure中并不一定等同于它们不被空格分隔的情况

但是,
token
似乎不能在任何地方都使用,因此仅将其放在
seq
的上述各种用法上可能不起作用。我的猜测是,大致上,如果
seq
的所有参数都是令牌,
token
可以在
seq
周围使用

下面是一个处理提供的4个测试用例的示例。AFAICT说,尽管事物被解析为不同的东西,人们仍然可以做出适当的区分

const JAVA_ID = /[a-zA-Z_]\w*/;

module.exports = grammar({

    name: 'clojure',

    extras: $ =>
        [/[\s,]/],

    rules: {
        program: $ =>
            repeat($._anything),

        _anything: $ =>
            choice($.symbol,
                   $.member_access,
                   $.new_class),

        symbol: $ =>
            choice($._symbol_chars,
                   $.scoped_identifier),

        // XXX: approximate, see: https://clojure.org/reader
        _symbol_chars: $ =>
            /[a-zA-Z\*\+\!\-_\?][\w\*\+\!\-\?\':]*/,

        // XXX: except $ can be used too for inner classes?
        scoped_identifier: $ =>
            token(seq(JAVA_ID,
                      repeat(seq('.', JAVA_ID)))),

        // e.g. .toUpperCase
        member_access: $ =>
            token(seq('.',
                      JAVA_ID,
                      repeat(seq('.', JAVA_ID)))),

        // e.g. java.lang.String.
        new_class: $ =>
            token(seq(JAVA_ID,
                      repeat(seq('.', JAVA_ID)),
                      '.')),

    }
});

function sep1 (rule, separator) {
    return seq(rule, repeat(seq(separator, rule)));
}
请注意,tree sitter cli的版本可能很重要——我使用了0.16.4。当我尝试你的语法时,我没有得到与你相同的输出

(作用域标识符
位的灵感来自tree sitter java语法中同名的东西。)


(另一方面,关于树保姆的问题似乎正在树保姆github存储库中解决。那里有一些问题提到了其他讨论场所的可能性,但我还没有看到任何结果。你可能会在那里得到更好的答案。)

我所缺少的是
令牌的使用。这就是我一直在寻找的答案。非常感谢。