Deal with quantifiers appearing on capture's enclosing patterns

- Use a proper enum type for quantifiers.
- Drop quantifiers from `TSQueryStep`, which was not used.
- Keep track of the captures introduced during a pattern parse, and
  apply the quantifier for the pattern to the captures that were
  introduced by the pattern or any sub patterns.
- Use 'quantifier' instead of 'suffix'.
This commit is contained in:
Hendrik van Antwerpen 2021-12-01 19:05:41 +01:00
parent ae7869d1a6
commit 9bac066330
4 changed files with 131 additions and 59 deletions

View file

@ -107,6 +107,11 @@ pub struct TSQueryCapture {
pub node: TSNode,
pub index: u32,
}
pub const TSQuantifier_One: TSQuantifier = 0;
pub const TSQuantifier_OneOrMore: TSQuantifier = 1;
pub const TSQuantifier_ZeroOrOne: TSQuantifier = 2;
pub const TSQuantifier_ZeroOrMore: TSQuantifier = 3;
pub type TSQuantifier = u32;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct TSQueryMatch {
@ -666,13 +671,10 @@ extern "C" {
) -> *const ::std::os::raw::c_char;
}
extern "C" {
#[doc = " Get the suffix of one of the query's captures, or one of the query's"]
#[doc = " string literals. Each capture and string is associated with a numeric"]
#[doc = " id based on the order that it appeared in the query's source."]
pub fn ts_query_capture_suffix_for_id(
arg1: *const TSQuery,
id: u32,
) -> ::std::os::raw::c_char;
#[doc = " Get the quantifier of the query's captures, or one of the query's string"]
#[doc = " literals. Each capture and string is associated with a numeric id based"]
#[doc = " on the order that it appeared in the query's source."]
pub fn ts_query_capture_quantifier_for_id(arg1: *const TSQuery, id: u32) -> TSQuantifier;
}
extern "C" {
pub fn ts_query_string_value_for_id(

View file

@ -98,30 +98,30 @@ pub struct TreeCursor<'a>(ffi::TSTreeCursor, PhantomData<&'a ()>);
pub struct Query {
ptr: NonNull<ffi::TSQuery>,
capture_names: Vec<String>,
capture_suffixes: Vec<QueryCaptureSuffix>,
capture_quantifiers: Vec<Quantifier>,
text_predicates: Vec<Box<[TextPredicate]>>,
property_settings: Vec<Box<[QueryProperty]>>,
property_predicates: Vec<Box<[(QueryProperty, bool)]>>,
general_predicates: Vec<Box<[QueryPredicate]>>,
}
/// A suffix indicating the multiplicity of the capture value
/// A quantifier for captures
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum QueryCaptureSuffix {
pub enum Quantifier {
One,
OneOrMore,
ZeroOrMore,
ZeroOrOne,
ZeroOrMore,
}
impl From<u8> for QueryCaptureSuffix {
fn from(value: u8) -> QueryCaptureSuffix {
impl From<ffi::TSQuantifier> for Quantifier {
fn from(value: ffi::TSQuantifier) -> Self {
match value {
b'\0' => QueryCaptureSuffix::One,
b'+' => QueryCaptureSuffix::OneOrMore,
b'*' => QueryCaptureSuffix::ZeroOrMore,
b'?' => QueryCaptureSuffix::ZeroOrOne,
_ => panic!("Unrecognized suffix: {}", value as char),
ffi::TSQuantifier_One => Quantifier::One,
ffi::TSQuantifier_OneOrMore => Quantifier::OneOrMore,
ffi::TSQuantifier_ZeroOrOne => Quantifier::ZeroOrOne,
ffi::TSQuantifier_ZeroOrMore => Quantifier::ZeroOrMore,
_ => panic!("Unrecognized quantifier: {}", value),
}
}
}
@ -1328,7 +1328,7 @@ impl Query {
let mut result = Query {
ptr: unsafe { NonNull::new_unchecked(ptr) },
capture_names: Vec::with_capacity(capture_count as usize),
capture_suffixes: Vec::with_capacity(capture_count as usize),
capture_quantifiers: Vec::with_capacity(capture_count as usize),
text_predicates: Vec::with_capacity(pattern_count),
property_predicates: Vec::with_capacity(pattern_count),
property_settings: Vec::with_capacity(pattern_count),
@ -1344,8 +1344,8 @@ impl Query {
let name = slice::from_raw_parts(name, length as usize);
let name = str::from_utf8_unchecked(name);
result.capture_names.push(name.to_string());
let suffix = ffi::ts_query_capture_suffix_for_id(ptr, i) as u8;
result.capture_suffixes.push(suffix.into());
let quantifier = ffi::ts_query_capture_quantifier_for_id(ptr, i);
result.capture_quantifiers.push(quantifier.into());
}
}
@ -1549,9 +1549,9 @@ impl Query {
&self.capture_names
}
/// Get the suffixes of the captures used in the query.
pub fn capture_suffixes(&self) -> &[QueryCaptureSuffix] {
&self.capture_suffixes
/// Get the quantifiers of the captures used in the query.
pub fn capture_quantifiers(&self) -> &[Quantifier] {
&self.capture_quantifiers
}
/// Get the index for a given capture name.