使用 crate syn 提前查找“=>”令牌

Lookahead for "=>" token with crate syn

我正在使用 proc-macros 和 syn 开发一种特定领域的小语言,我想在其中解析表单上的一系列运算符

 lhs + rsh => res
 lhs - rsh => res

 lhs += rsh
 lhs -= rsh

等等。

我正在使用 syn 板条箱执行此操作,为我需要的各种结构实现 Parser。我的想法是,我可以在前三个标记之后使用前瞻来解析这些标记,如下所示:

let lookahead = input.lookahead1();
            
let lhs = input.parse()?;
let op = input.parse()?;
let rhs = input.parse()?;

// now, conditionally parse the res part of an operator
let res = if lookahead.peek(syn::token::FatArrow) {
    input.parse::<syn::token::FatArrow>()?;
    Some(input.parse()?)
} else { None };

问题是虽然 syn::token::FatArrow 在调用 parse 时是 => 的标记,但在调用 peek.[=22 时似乎不是=]

// This says false
println!("do we see =>? {}", lookahead.peek(syn::token::FatArrow));
// this also says false
println!("do we see =>? {}", lookahead.peek(Token![=>]));

解析没问题,但如果我不能向前看,那么我就无法区分这两种情况。 (好吧,我可以通过分叉输入流并尝试两种规则,然后用有效的流替换流,但是当下一个标记出现峰值时,这似乎有点戏剧化,如果我知道如何解决问题的话).

我在这里做错了什么?我是否需要使用其他参数调用 peek 来匹配令牌 =>

创建 Lookahead1 的时间很重要:它指向 光标在调用 lookahead1() 时所在的位置。 Lookahead1 用于当您有一个可能值的列表,并且您希望在该值无效时提供一个很好的错误消息,列出所有可能的值。如果您只想查看下一个令牌,请使用 ParseBuffer::peek():

let res = if input.peek(syn::token::FatArrow) {
    input.parse::<syn::token::FatArrow>()?;
    Some(input.parse()?)
} else { None };