Как сопоставить ключевые слова с вредителями?

#rust #pest

Вопрос:

Я пытаюсь разобрать такую строку

 MyTupleComponent str, str
 

с грамматикой

 cname = _{ (ASCII_ALPHANUMERIC | "_")  }

ints = { "i8" | "i16" | "i32" | "i64" | "i128" | "isize" }
uints = { "u8" | "u16" | "u32" | "u64" | "u128" | "usize" }
strings = { "str" | "String" }
types = { strings | ints | uints }

tuple_component = { cname ~ (types ~ ("," ~ types)?)  }
 

Но в конечном итоге с

 Err(Error { variant: ParsingError { positives: [types], negatives: [] }, location: Pos(20), line_col: Pos((1, 21)), path: None, line: "MyTupleComponent str, str", continued_line: None })
 

Кто-нибудь знает, почему правило не соответствует правильно?

Комментарии:

1. Похоже, вам нужно добавить некоторое соответствие для пробелов, например SPACE_SEPARATOR .

Ответ №1:

Вы можете выбрать две дороги:

Как отметил @ZachThompson, определите WHITESPACE . Если да, сделайте cname атомарный, чтобы он не захватывал буквенно-цифровые символы И пробелы.

Эта тестовая грамматика кажется прекрасной:

 WHITESPACE = _{ " " }
cname = @{ (ASCII_ALPHANUMERIC | "_")  }

ints = { "i8" | "i16" | "i32" | "i64" | "i128" | "isize" }
uints = { "u8" | "u16" | "u32" | "u64" | "u128" | "usize" }
strings = { "str" | "String" }
types = { strings | ints | uints }

tuple_component = { cname ~ (types ~ ("," ~ types)?)  }

file = { tuple_component ~ EOI }
 

В противном случае вы можете указать пробелы вручную. Этот подход тоже сработал бы, но он не масштабируется с ростом грамматики.

P.S. Намерены ли вы анализировать выражения типа MyTupleComponent str, str str, str , без запятой, чтобы отделить второй кортеж от первого? В настоящее время он отлично разбирается. Возможно, вы захотите упростить правило, чтобы

 tuple_component = { cname ~ types ~ ("," ~ types)* }