macro_rules! err {
[$self:expr, $msg:literal] => {
$self.create_diagnostic($self.span(), String::from($msg))
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
#[allow(dead_code)]
pub enum Rule {
Action,
Alternation,
Assertion,
Commit,
Concat,
Decl,
Error,
File,
Name,
NodeCreation,
NodeElision,
NodeMarker,
NodeRename,
Optional,
OrderedChoice,
Paren,
PartDecl,
Plus,
Postfix,
Predicate,
Regex,
Return,
RightDecl,
RuleDecl,
SkipDecl,
Star,
StartDecl,
Symbol,
TokenDecl,
TokenList,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct NodeRef(pub usize);
impl NodeRef {
#[allow(dead_code)]
pub const ROOT: NodeRef = NodeRef(0);
}
#[cfg(target_pointer_width = "64")]
#[derive(Copy, Clone)]
pub struct CstIndex([u8; 6]);
#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
#[derive(Copy, Clone)]
pub struct CstIndex(usize);
impl std::fmt::Debug for CstIndex {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
usize::from(*self).fmt(f)
}
}
impl From<CstIndex> for usize {
#[cfg(target_pointer_width = "64")]
#[inline]
fn from(value: CstIndex) -> Self {
let [b0, b1, b2, b3, b4, b5] = value.0;
usize::from_le_bytes([b0, b1, b2, b3, b4, b5, 0, 0])
}
#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
#[inline]
fn from(value: CstIndex) -> Self {
value.0
}
}
impl From<usize> for CstIndex {
#[cfg(target_pointer_width = "64")]
#[inline]
fn from(value: usize) -> Self {
let [b0, b1, b2, b3, b4, b5, b6, b7] = value.to_le_bytes();
debug_assert!(b6 == 0 && b7 == 0);
Self([b0, b1, b2, b3, b4, b5])
}
#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
#[inline]
fn from(value: usize) -> Self {
Self(value)
}
}
#[derive(Debug, Copy, Clone)]
pub enum Node {
Rule(Rule, CstIndex),
Token(Token, CstIndex),
}
#[derive(Clone, Copy)]
struct MarkOpened(usize);
#[derive(Clone, Copy)]
struct MarkClosed(usize);
#[derive(Clone)]
struct MarkTruncation {
node_count: usize,
token_count: usize,
non_skip_len: usize,
}
#[derive(Default)]
pub struct CstChildren<'a> {
iter: std::slice::Iter<'a, Node>,
offset: usize,
}
impl Iterator for CstChildren<'_> {
type Item = NodeRef;
fn next(&mut self) -> Option<Self::Item> {
let offset = self.offset;
self.offset += 1;
if let Some(node) = self.iter.next() {
if let Node::Rule(_, end_offset) = node {
let end_offset = usize::from(*end_offset);
if end_offset > 0 {
self.iter.nth(end_offset.saturating_sub(1));
self.offset += end_offset;
}
}
Some(NodeRef(offset))
} else {
None
}
}
}
pub type Span = core::ops::Range<usize>;
#[derive(Debug)]
pub struct CstData {
spans: Vec<Span>,
nodes: Vec<Node>,
token_count: usize,
non_skip_len: usize,
}
#[allow(dead_code)]
impl CstData {
fn new(spans: Vec<Span>) -> Self {
let nodes = Vec::with_capacity(spans.len() * 2);
Self {
spans,
nodes,
token_count: 0,
non_skip_len: 0,
}
}
fn open(&mut self) -> MarkOpened {
let mark = MarkOpened(self.nodes.len());
self.nodes.push(Node::Rule(Rule::Error, 0.into()));
self.non_skip_len = self.nodes.len();
mark
}
fn close(&mut self, mark: MarkOpened, rule: Rule) -> MarkClosed {
let len = self.non_skip_len - 1;
self.nodes[mark.0] = Node::Rule(
rule,
if mark.0 > len {
self.non_skip_len += mark.0 - len;
0
} else {
len - mark.0
}
.into(),
);
MarkClosed(mark.0)
}
fn close_root(&mut self, mark: MarkOpened, rule: Rule) -> MarkClosed {
self.nodes[mark.0] = Node::Rule(rule, (self.nodes.len() - 1 - mark.0).into());
MarkClosed(mark.0)
}
fn advance(&mut self, token: Token, skip: bool) {
self.nodes.push(Node::Token(token, self.token_count.into()));
self.token_count += 1;
if !skip {
self.non_skip_len = self.nodes.len();
}
}
fn open_before(&mut self, mark: MarkClosed) -> MarkOpened {
self.nodes.insert(mark.0, Node::Rule(Rule::Error, 0.into()));
self.non_skip_len += 1;
MarkOpened(mark.0)
}
fn mark(&self) -> MarkClosed {
MarkClosed(self.nodes.len())
}
fn mark_truncation(&self) -> MarkTruncation {
MarkTruncation {
node_count: self.nodes.len(),
token_count: self.token_count,
non_skip_len: self.non_skip_len,
}
}
fn truncate(&mut self, mark: MarkTruncation) {
self.nodes.truncate(mark.node_count);
self.token_count = mark.token_count;
self.non_skip_len = mark.non_skip_len;
}
pub fn children(&self, node_ref: NodeRef) -> CstChildren<'_> {
let iter = if let Node::Rule(_, end_offset) = self.nodes[node_ref.0] {
self.nodes[node_ref.0 + 1..node_ref.0 + usize::from(end_offset) + 1].iter()
} else {
std::slice::Iter::default()
};
CstChildren {
iter,
offset: node_ref.0 + 1,
}
}
pub fn get(&self, node_ref: NodeRef) -> Node {
self.nodes[node_ref.0]
}
pub fn span(&self, node_ref: NodeRef) -> Span {
fn find_token<'a>(mut iter: impl Iterator<Item = &'a Node>) -> Option<usize> {
iter.find_map(|node| match node {
Node::Rule(..) => None,
Node::Token(_, idx) => Some(usize::from(*idx)),
})
}
match self.nodes[node_ref.0] {
Node::Token(_, idx) => self.spans[usize::from(idx)].clone(),
Node::Rule(_, end_offset) => {
let end = node_ref.0 + usize::from(end_offset);
let first = find_token(self.nodes[node_ref.0 + 1..=end].iter());
let last = find_token(self.nodes[node_ref.0 + 1..=end].iter().rev());
if let (Some(first), Some(last)) = (first, last) {
self.spans[first].start..self.spans[last].end
} else {
let offset = find_token(self.nodes[..node_ref.0].iter().rev())
.map_or(0, |before| self.spans[before].end);
offset..offset
}
}
}
}
pub fn match_token(&self, node_ref: NodeRef, matched_token: Token) -> Option<Span> {
match self.nodes[node_ref.0] {
Node::Token(token, idx) if token == matched_token => {
Some(self.spans[usize::from(idx)].clone())
}
_ => None,
}
}
pub fn match_rule(&self, node_ref: NodeRef, matched_rule: Rule) -> bool {
matches!(self.nodes[node_ref.0], Node::Rule(rule, _) if rule == matched_rule)
}
}
#[derive(Debug)]
pub struct Cst<'a> {
source: &'a str,
data: CstData,
}
#[allow(dead_code)]
impl<'a> Cst<'a> {
pub fn source(&self) -> &'a str {
self.source
}
pub fn into_data(self) -> CstData {
self.data
}
pub fn children(&self, node_ref: NodeRef) -> CstChildren<'_> {
self.data.children(node_ref)
}
pub fn get(&self, node_ref: NodeRef) -> Node {
self.data.get(node_ref)
}
pub fn span(&self, node_ref: NodeRef) -> Span {
self.data.span(node_ref)
}
pub fn match_token(&self, node_ref: NodeRef, matched_token: Token) -> Option<(&'a str, Span)> {
self.data
.match_token(node_ref, matched_token)
.map(|span| (&self.source[span.clone()], span))
}
pub fn match_rule(&self, node_ref: NodeRef, matched_rule: Rule) -> bool {
self.data.match_rule(node_ref, matched_rule)
}
pub fn span_text(&self, span_idx: CstIndex) -> &'a str {
&self.source[self.data.spans[usize::from(span_idx)].clone()]
}
}
impl std::fmt::Display for Cst<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
const DEPTH: &str = " ";
fn rec(
cst: &Cst<'_>,
f: &mut std::fmt::Formatter<'_>,
node_ref: NodeRef,
indent: usize,
) -> std::fmt::Result {
match cst.get(node_ref) {
Node::Rule(rule, _) => {
let span = cst.span(node_ref);
writeln!(f, "{}{rule:?} [{span:?}]", DEPTH.repeat(indent))?;
for child_node_ref in cst.children(node_ref) {
rec(cst, f, child_node_ref, indent + 1)?;
}
Ok(())
}
Node::Token(token, idx) => {
let span = &cst.data.spans[usize::from(idx)];
writeln!(
f,
"{}{:?} {:?} [{:?}]",
DEPTH.repeat(indent),
token,
&cst.source[span.clone()],
span,
)
}
}
}
rec(self, f, NodeRef::ROOT, 0)
}
}
impl std::fmt::Debug for Rule {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Rule::Action => write!(f, "action"),
Rule::Alternation => write!(f, "alternation"),
Rule::Assertion => write!(f, "assertion"),
Rule::Commit => write!(f, "commit"),
Rule::Concat => write!(f, "concat"),
Rule::Decl => write!(f, "decl"),
Rule::Error => write!(f, "error"),
Rule::File => write!(f, "file"),
Rule::Name => write!(f, "name"),
Rule::NodeCreation => write!(f, "node_creation"),
Rule::NodeElision => write!(f, "node_elision"),
Rule::NodeMarker => write!(f, "node_marker"),
Rule::NodeRename => write!(f, "node_rename"),
Rule::Optional => write!(f, "optional"),
Rule::OrderedChoice => write!(f, "ordered_choice"),
Rule::Paren => write!(f, "paren"),
Rule::PartDecl => write!(f, "part_decl"),
Rule::Plus => write!(f, "plus"),
Rule::Postfix => write!(f, "postfix"),
Rule::Predicate => write!(f, "predicate"),
Rule::Regex => write!(f, "regex"),
Rule::Return => write!(f, "return"),
Rule::RightDecl => write!(f, "right_decl"),
Rule::RuleDecl => write!(f, "rule_decl"),
Rule::SkipDecl => write!(f, "skip_decl"),
Rule::Star => write!(f, "star"),
Rule::StartDecl => write!(f, "start_decl"),
Rule::Symbol => write!(f, "symbol"),
Rule::TokenDecl => write!(f, "token_decl"),
Rule::TokenList => write!(f, "token_list"),
}
}
}
macro_rules! expect {
($token:ident, $msg:literal, $self:expr, $diags:expr) => {
if let Token::$token = $self.current {
$self.advance(false, $diags);
} else {
$self.error($diags, err![$self, $msg]);
}
};
}
#[allow(unused_macros)]
macro_rules! try_expect {
($token:ident, $msg:literal, $self:expr, $diags:expr) => {
if let Token::$token = $self.current {
$self.advance(false, $diags);
} else {
if $self.in_ordered_choice {
return None;
}
$self.error($diags, err![$self, $msg]);
}
};
}
struct ParserState {
pos: usize,
current: Token,
truncation_mark: MarkTruncation,
diag_count: usize,
}
pub struct Parser<'a> {
cst: Cst<'a>,
tokens: Vec<Token>,
pos: usize,
current: Token,
end_of_input: Token,
max_offset: usize,
#[allow(dead_code)]
context: <Self as ParserCallbacks<'a>>::Context,
error_node: Option<MarkOpened>,
#[allow(dead_code)]
in_ordered_choice: bool,
error_since_advance: bool,
}
#[allow(clippy::while_let_loop, dead_code, unused_parens)]
impl<'a> Parser<'a> {
fn active_error(&self) -> bool {
self.error_node.is_some() || self.error_since_advance
}
fn error(
&mut self,
diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>,
diag: <Self as ParserCallbacks<'a>>::Diagnostic,
) {
if self.active_error() {
return;
}
self.error_since_advance = true;
diags.push(diag);
}
fn advance(&mut self, error: bool, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
if !error {
self.close_error_node(diags);
self.error_since_advance = false;
}
self.cst.data.advance(self.current, false);
loop {
self.pos += 1;
match self.tokens.get(self.pos) {
Some(
token @ (Token::Error
| Token::LineComment
| Token::BlockComment
| Token::DocComment
| Token::Whitespace),
) => {
self.cst.data.advance(*token, true);
continue;
}
Some(token) if self.predicate_skip(*token) => {
self.cst.data.advance(*token, true);
continue;
}
Some(token) => {
self.current = *token;
break;
}
None => {
self.current = self.end_of_input;
break;
}
}
}
}
fn is_skipped(token: Token) -> bool {
matches!(
token,
Token::Error
| Token::LineComment
| Token::BlockComment
| Token::DocComment
| Token::Whitespace
)
}
fn init_skip(&mut self) {
loop {
match self.tokens.get(self.pos) {
Some(
token @ (Token::Error
| Token::LineComment
| Token::BlockComment
| Token::DocComment
| Token::Whitespace),
) => {
self.pos += 1;
self.cst.data.advance(*token, true);
continue;
}
Some(token) if self.predicate_skip(*token) => {
self.pos += 1;
self.cst.data.advance(*token, true);
continue;
}
Some(token) => {
self.current = *token;
break;
}
None => {
self.current = self.end_of_input;
break;
}
}
}
}
fn advance_with_error(
&mut self,
diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>,
diag: <Self as ParserCallbacks<'a>>::Diagnostic,
) {
self.error(diags, diag);
if self.error_node.is_none() {
self.error_node = Some(self.cst.data.open());
}
self.advance(true, diags);
}
fn peek(&self, lookahead: usize) -> Token {
self.tokens
.iter()
.skip(self.pos)
.filter(|token| !Self::is_skipped(**token))
.nth(lookahead)
.map_or(self.end_of_input, |it| *it)
}
fn peek_left(&self, lookbehind: usize) -> Token {
self.tokens
.iter()
.take(self.pos + 1)
.rev()
.filter(|token| !Self::is_skipped(**token))
.nth(lookbehind)
.map_or(self.end_of_input, |it| *it)
}
fn close_error_node(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
if let Some(error_node) = self.error_node {
self.cst.data.close(error_node, Rule::Error);
self.create_node_error(NodeRef(error_node.0), diags);
self.error_node = None;
}
}
fn open(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) -> MarkOpened {
self.close_error_node(diags);
self.cst.data.open()
}
fn open_before(
&mut self,
mark: MarkClosed,
diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>,
) -> MarkOpened {
self.close_error_node(diags);
self.cst.data.open_before(mark)
}
fn close(
&mut self,
mark: MarkOpened,
rule: Rule,
diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>,
) -> MarkClosed {
self.close_error_node(diags);
self.cst.data.close(mark, rule)
}
fn close_root(
&mut self,
mark: MarkOpened,
rule: Rule,
diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>,
) -> MarkClosed {
self.close_error_node(diags);
self.cst.data.close_root(mark, rule)
}
fn mark(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) -> MarkClosed {
self.close_error_node(diags);
self.cst.data.mark()
}
fn span(&self) -> Span {
self.cst
.data
.spans
.get(self.pos)
.map_or(self.max_offset..self.max_offset, |span| span.clone())
}
fn get_state(&self, diags: &[<Self as ParserCallbacks<'a>>::Diagnostic]) -> ParserState {
ParserState {
pos: self.pos,
current: self.current,
truncation_mark: self.cst.data.mark_truncation(),
diag_count: diags.len(),
}
}
fn set_state(
&mut self,
state: &ParserState,
diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>,
) {
self.pos = state.pos;
self.current = state.current;
diags.truncate(state.diag_count);
for i in state.truncation_mark.node_count..self.cst.data.nodes.len() {
if let Node::Rule(rule, _) = self.cst.data.nodes[i] {
self.delete_node(rule, NodeRef(i));
}
}
self.cst.data.truncate(state.truncation_mark.clone());
}
fn create_node(
&mut self,
rule: Rule,
node_ref: NodeRef,
diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>,
) {
match rule {
Rule::Action => self.create_node_action(node_ref, diags),
Rule::Alternation => self.create_node_alternation(node_ref, diags),
Rule::Assertion => self.create_node_assertion(node_ref, diags),
Rule::Commit => self.create_node_commit(node_ref, diags),
Rule::Concat => self.create_node_concat(node_ref, diags),
Rule::Decl => self.create_node_decl(node_ref, diags),
Rule::Error => self.create_node_error(node_ref, diags),
Rule::File => self.create_node_file(node_ref, diags),
Rule::Name => self.create_node_name(node_ref, diags),
Rule::NodeCreation => self.create_node_node_creation(node_ref, diags),
Rule::NodeElision => self.create_node_node_elision(node_ref, diags),
Rule::NodeMarker => self.create_node_node_marker(node_ref, diags),
Rule::NodeRename => self.create_node_node_rename(node_ref, diags),
Rule::Optional => self.create_node_optional(node_ref, diags),
Rule::OrderedChoice => self.create_node_ordered_choice(node_ref, diags),
Rule::Paren => self.create_node_paren(node_ref, diags),
Rule::PartDecl => self.create_node_part_decl(node_ref, diags),
Rule::Plus => self.create_node_plus(node_ref, diags),
Rule::Postfix => self.create_node_postfix(node_ref, diags),
Rule::Predicate => self.create_node_predicate(node_ref, diags),
Rule::Regex => self.create_node_regex(node_ref, diags),
Rule::Return => self.create_node_return(node_ref, diags),
Rule::RightDecl => self.create_node_right_decl(node_ref, diags),
Rule::RuleDecl => self.create_node_rule_decl(node_ref, diags),
Rule::SkipDecl => self.create_node_skip_decl(node_ref, diags),
Rule::Star => self.create_node_star(node_ref, diags),
Rule::StartDecl => self.create_node_start_decl(node_ref, diags),
Rule::Symbol => self.create_node_symbol(node_ref, diags),
Rule::TokenDecl => self.create_node_token_decl(node_ref, diags),
Rule::TokenList => self.create_node_token_list(node_ref, diags),
}
}
fn delete_node(&mut self, _rule: Rule, _node_ref: NodeRef) {}
pub fn new_with_context(
source: &'a str,
diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>,
mut context: <Self as ParserCallbacks<'a>>::Context,
) -> Parser<'a> {
let (tokens, spans) = Self::create_tokens(&mut context, source, diags);
let max_offset = source.len();
Self {
current: Token::EOF,
end_of_input: Token::EOF,
cst: Cst {
data: CstData::new(spans),
source,
},
tokens,
pos: 0,
max_offset,
context,
error_node: None,
in_ordered_choice: false,
error_since_advance: false,
}
}
pub fn new(
source: &'a str,
diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>,
) -> Parser<'a>
where
<Self as ParserCallbacks<'a>>::Context: Default,
{
#[allow(clippy::unit_arg)]
Self::new_with_context(
source,
diags,
<Self as ParserCallbacks<'a>>::Context::default(),
)
}
fn parse_rule<
RuleParser: Fn(&mut Self, &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>),
>(
mut self,
rule: RuleParser,
diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>,
root: Rule,
) -> Cst<'a> {
let token_count = self.tokens.len();
let m = self.open(diags);
self.init_skip();
rule(&mut self, diags);
self.close_error_node(diags);
if self.pos != token_count {
self.error(diags, err![self, "invalid syntax, expected: <end of file>"]);
let error_tree = self.open(diags);
while self.pos < token_count {
let token = self.tokens[self.pos];
self.cst.data.advance(token, Self::is_skipped(token));
self.pos += 1;
}
self.cst.data.close(error_tree, Rule::Error);
self.create_node_error(NodeRef(error_tree.0), diags);
}
let closed = self.cst.data.close_root(m, root);
self.create_node(root, NodeRef(closed.0), diags);
self.cst
}
pub fn parse(self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) -> Cst<'a> {
self.parse_rule(|parser, diags| parser.rule_file(diags), diags, Rule::File)
}
fn rule_file(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
loop {
match self.current {
Token::Id
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.rule_decl(diags);
}
Token::EOF => break,
_ => {
self.advance_with_error(diags, err![self, "invalid syntax, expected one of: <end of file>, <identifier>, \'part\', \'right\', \'skip\', \'start\', \'token\'"]);
}
}
}
}
fn rule_decl(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
match self.current {
Token::Token => {
self.rule_token_list(diags);
}
Token::Id if self.predicate_decl_1() => {
self.rule_rule_decl(diags);
}
Token::Start => {
self.rule_start_decl(diags);
}
Token::Right => {
self.rule_right_decl(diags);
}
Token::Skip => {
self.rule_skip_decl(diags);
}
Token::Part => {
self.rule_part_decl(diags);
}
Token::Id => {
self.advance_with_error(diags, err![self, "invalid syntax"]);
}
_ => {
self.error(diags, err![self, "invalid syntax, expected one of: <identifier>, \'part\', \'right\', \'skip\', \'start\', \'token\'"]);
}
}
}
fn rule_start_decl(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
let m = self.open(diags);
expect!(Start, "invalid syntax, expected: \'start\'", self, diags);
expect!(Id, "invalid syntax, expected: <identifier>", self, diags);
expect!(Semi, "invalid syntax, expected: \';\'", self, diags);
let closed = self.close(m, Rule::StartDecl, diags);
self.create_node_start_decl(NodeRef(closed.0), diags);
}
fn rule_right_decl(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
let m = self.open(diags);
expect!(Right, "invalid syntax, expected: \'right\'", self, diags);
match self.current {
Token::Id => {
expect!(Id, "invalid syntax, expected: <identifier>", self, diags);
}
Token::Str => {
expect!(
Str,
"invalid syntax, expected: <string literal>",
self,
diags
);
}
_ => {
self.error(
diags,
err![
self,
"invalid syntax, expected one of: <identifier>, <string literal>"
],
);
}
}
loop {
match self.current {
Token::Id | Token::Str => {
match self.current {
Token::Id => {
expect!(Id, "invalid syntax, expected: <identifier>", self, diags);
}
Token::Str => {
expect!(
Str,
"invalid syntax, expected: <string literal>",
self,
diags
);
}
_ => {
self.error(diags, err![self, "invalid syntax, expected one of: <identifier>, <string literal>"]);
}
}
}
Token::Semi => break,
Token::EOF
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.error(diags, err![self, "invalid syntax, expected one of: <identifier>, \';\', <string literal>"]);
break;
}
_ => {
self.advance_with_error(diags, err![self, "invalid syntax, expected one of: <identifier>, \';\', <string literal>"]);
}
}
}
expect!(Semi, "invalid syntax, expected: \';\'", self, diags);
let closed = self.close(m, Rule::RightDecl, diags);
self.create_node_right_decl(NodeRef(closed.0), diags);
}
fn rule_skip_decl(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
let m = self.open(diags);
expect!(Skip, "invalid syntax, expected: \'skip\'", self, diags);
match self.current {
Token::Id => {
expect!(Id, "invalid syntax, expected: <identifier>", self, diags);
}
Token::Str => {
expect!(
Str,
"invalid syntax, expected: <string literal>",
self,
diags
);
}
_ => {
self.error(
diags,
err![
self,
"invalid syntax, expected one of: <identifier>, <string literal>"
],
);
}
}
loop {
match self.current {
Token::Id | Token::Str => {
match self.current {
Token::Id => {
expect!(Id, "invalid syntax, expected: <identifier>", self, diags);
}
Token::Str => {
expect!(
Str,
"invalid syntax, expected: <string literal>",
self,
diags
);
}
_ => {
self.error(diags, err![self, "invalid syntax, expected one of: <identifier>, <string literal>"]);
}
}
}
Token::Semi => break,
Token::EOF
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.error(diags, err![self, "invalid syntax, expected one of: <identifier>, \';\', <string literal>"]);
break;
}
_ => {
self.advance_with_error(diags, err![self, "invalid syntax, expected one of: <identifier>, \';\', <string literal>"]);
}
}
}
expect!(Semi, "invalid syntax, expected: \';\'", self, diags);
let closed = self.close(m, Rule::SkipDecl, diags);
self.create_node_skip_decl(NodeRef(closed.0), diags);
}
fn rule_part_decl(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
let m = self.open(diags);
expect!(Part, "invalid syntax, expected: \'part\'", self, diags);
expect!(Id, "invalid syntax, expected: <identifier>", self, diags);
loop {
match self.current {
Token::Id => {
expect!(Id, "invalid syntax, expected: <identifier>", self, diags);
}
Token::Semi => break,
Token::EOF
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.error(
diags,
err![self, "invalid syntax, expected one of: <identifier>, \';\'"],
);
break;
}
_ => {
self.advance_with_error(
diags,
err![self, "invalid syntax, expected one of: <identifier>, \';\'"],
);
}
}
}
expect!(Semi, "invalid syntax, expected: \';\'", self, diags);
let closed = self.close(m, Rule::PartDecl, diags);
self.create_node_part_decl(NodeRef(closed.0), diags);
}
fn rule_token_list(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
let m = self.open(diags);
expect!(Token, "invalid syntax, expected: \'token\'", self, diags);
self.rule_token_decl(diags);
loop {
match self.current {
Token::Id => {
self.rule_token_decl(diags);
}
Token::Semi => break,
Token::EOF
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.error(
diags,
err![self, "invalid syntax, expected one of: <identifier>, \';\'"],
);
break;
}
_ => {
self.advance_with_error(
diags,
err![self, "invalid syntax, expected one of: <identifier>, \';\'"],
);
}
}
}
expect!(Semi, "invalid syntax, expected: \';\'", self, diags);
let closed = self.close(m, Rule::TokenList, diags);
self.create_node_token_list(NodeRef(closed.0), diags);
}
fn rule_token_decl(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
let m = self.open(diags);
expect!(Id, "invalid syntax, expected: <identifier>", self, diags);
loop {
match self.current {
Token::Equal => {
expect!(Equal, "invalid syntax, expected: \'=\'", self, diags);
expect!(
Str,
"invalid syntax, expected: <string literal>",
self,
diags
);
break;
}
Token::Id | Token::Semi => break,
Token::EOF
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.error(
diags,
err![
self,
"invalid syntax, expected one of: \'=\', <identifier>, \';\'"
],
);
break;
}
_ => {
self.advance_with_error(
diags,
err![
self,
"invalid syntax, expected one of: \'=\', <identifier>, \';\'"
],
);
}
}
}
let closed = self.close(m, Rule::TokenDecl, diags);
self.create_node_token_decl(NodeRef(closed.0), diags);
}
fn rule_rule_decl(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
let m = self.open(diags);
expect!(Id, "invalid syntax, expected: <identifier>", self, diags);
loop {
match self.current {
Token::Hat => {
expect!(Hat, "invalid syntax, expected: \'^\'", self, diags);
break;
}
Token::Colon => break,
Token::EOF
| Token::Id
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.error(
diags,
err![self, "invalid syntax, expected one of: \':\', \'^\'"],
);
break;
}
_ => {
self.advance_with_error(
diags,
err![self, "invalid syntax, expected one of: \':\', \'^\'"],
);
}
}
}
expect!(Colon, "invalid syntax, expected: \':\'", self, diags);
loop {
match self.current {
Token::Action
| Token::And
| Token::Assertion
| Token::Hat
| Token::Id
| Token::LBrak
| Token::LPar
| Token::NodeCreation
| Token::NodeMarker
| Token::NodeRename
| Token::Predicate
| Token::Str
| Token::Tilde => {
self.rule_regex(diags);
break;
}
Token::Semi => break,
Token::EOF
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.error(diags, err![self, "invalid syntax, expected one of: <semantic action>, \'&\', <semantic assertion>, \'^\', <identifier>, \'[\', \'(\', <node creation>, <node marker>, <node rename>, <semantic predicate>, \';\', <string literal>, \'~\'"]);
break;
}
_ => {
self.advance_with_error(diags, err![self, "invalid syntax, expected one of: <semantic action>, \'&\', <semantic assertion>, \'^\', <identifier>, \'[\', \'(\', <node creation>, <node marker>, <node rename>, <semantic predicate>, \';\', <string literal>, \'~\'"]);
}
}
}
expect!(Semi, "invalid syntax, expected: \';\'", self, diags);
let closed = self.close(m, Rule::RuleDecl, diags);
self.create_node_rule_decl(NodeRef(closed.0), diags);
}
fn rule_regex(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
self.rule_alternation(diags);
}
fn rule_alternation(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
let start = self.mark(diags);
self.rule_ordered_choice(diags);
loop {
match self.current {
Token::Or => {
expect!(Or, "invalid syntax, expected: \'|\'", self, diags);
self.rule_ordered_choice(diags);
loop {
match self.current {
Token::Or => {
expect!(Or, "invalid syntax, expected: \'|\'", self, diags);
self.rule_ordered_choice(diags);
}
Token::RBrak | Token::RPar | Token::Semi => break,
Token::EOF
| Token::Id
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.error(diags, err![self, "invalid syntax, expected one of: \'|\', \']\', \')\', \';\'"]);
break;
}
_ => {
self.advance_with_error(diags, err![self, "invalid syntax, expected one of: \'|\', \']\', \')\', \';\'"]);
}
}
}
let open_node = self.open_before(start, diags);
self.close(open_node, Rule::Alternation, diags);
self.create_node_alternation(NodeRef(start.0), diags);
break;
}
Token::RBrak | Token::RPar | Token::Semi => break,
Token::EOF
| Token::Id
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.error(
diags,
err![
self,
"invalid syntax, expected one of: \'|\', \']\', \')\', \';\'"
],
);
break;
}
_ => {
self.advance_with_error(
diags,
err![
self,
"invalid syntax, expected one of: \'|\', \']\', \')\', \';\'"
],
);
}
}
}
}
fn rule_ordered_choice(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
let start = self.mark(diags);
self.rule_concat(diags);
loop {
match self.current {
Token::Slash => {
expect!(Slash, "invalid syntax, expected: \'/\'", self, diags);
self.rule_concat(diags);
loop {
match self.current {
Token::Slash => {
expect!(Slash, "invalid syntax, expected: \'/\'", self, diags);
self.rule_concat(diags);
}
Token::Or | Token::RBrak | Token::RPar | Token::Semi => break,
Token::EOF
| Token::Id
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.error(diags, err![self, "invalid syntax, expected one of: \'|\', \']\', \')\', \';\', \'/\'"]);
break;
}
_ => {
self.advance_with_error(diags, err![self, "invalid syntax, expected one of: \'|\', \']\', \')\', \';\', \'/\'"]);
}
}
}
let open_node = self.open_before(start, diags);
self.close(open_node, Rule::OrderedChoice, diags);
self.create_node_ordered_choice(NodeRef(start.0), diags);
break;
}
Token::Or | Token::RBrak | Token::RPar | Token::Semi => break,
Token::EOF
| Token::Id
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.error(
diags,
err![
self,
"invalid syntax, expected one of: \'|\', \']\', \')\', \';\', \'/\'"
],
);
break;
}
_ => {
self.advance_with_error(
diags,
err![
self,
"invalid syntax, expected one of: \'|\', \']\', \')\', \';\', \'/\'"
],
);
}
}
}
}
fn rule_concat(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
let start = self.mark(diags);
self.rule_postfix(diags);
loop {
match self.current {
Token::Action
| Token::And
| Token::Assertion
| Token::Hat
| Token::Id
| Token::LBrak
| Token::LPar
| Token::NodeCreation
| Token::NodeMarker
| Token::NodeRename
| Token::Predicate
| Token::Str
| Token::Tilde => {
self.rule_postfix(diags);
loop {
match self.current {
Token::Action
| Token::And
| Token::Assertion
| Token::Hat
| Token::Id
| Token::LBrak
| Token::LPar
| Token::NodeCreation
| Token::NodeMarker
| Token::NodeRename
| Token::Predicate
| Token::Str
| Token::Tilde => {
self.rule_postfix(diags);
}
Token::Or | Token::RBrak | Token::RPar | Token::Semi | Token::Slash => {
break
}
Token::EOF
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.error(diags, err![self, "invalid syntax, expected one of: <semantic action>, \'&\', <semantic assertion>, \'^\', <identifier>, \'[\', \'(\', <node creation>, <node marker>, <node rename>, \'|\', <semantic predicate>, \']\', \')\', \';\', \'/\', <string literal>, \'~\'"]);
break;
}
_ => {
self.advance_with_error(diags, err![self, "invalid syntax, expected one of: <semantic action>, \'&\', <semantic assertion>, \'^\', <identifier>, \'[\', \'(\', <node creation>, <node marker>, <node rename>, \'|\', <semantic predicate>, \']\', \')\', \';\', \'/\', <string literal>, \'~\'"]);
}
}
}
let open_node = self.open_before(start, diags);
self.close(open_node, Rule::Concat, diags);
self.create_node_concat(NodeRef(start.0), diags);
break;
}
Token::Or | Token::RBrak | Token::RPar | Token::Semi | Token::Slash => break,
Token::EOF
| Token::Part
| Token::Right
| Token::Skip
| Token::Start
| Token::Token => {
self.error(diags, err![self, "invalid syntax, expected one of: <semantic action>, \'&\', <semantic assertion>, \'^\', <identifier>, \'[\', \'(\', <node creation>, <node marker>, <node rename>, \'|\', <semantic predicate>, \']\', \')\', \';\', \'/\', <string literal>, \'~\'"]);
break;
}
_ => {
self.advance_with_error(diags, err![self, "invalid syntax, expected one of: <semantic action>, \'&\', <semantic assertion>, \'^\', <identifier>, \'[\', \'(\', <node creation>, <node marker>, <node rename>, \'|\', <semantic predicate>, \']\', \')\', \';\', \'/\', <string literal>, \'~\'"]);
}
}
}
}
#[allow(unused_assignments)]
fn rule_postfix(&mut self, diags: &mut Vec<<Self as ParserCallbacks<'a>>::Diagnostic>) {
fn rec<'a>(
parser: &mut Parser<'a>,
diags: &mut Vec<<Parser<'a> as ParserCallbacks<'a>>::Diagnostic>,
mut lhs: MarkClosed,
) {
let mut node_kind = Rule::Postfix;
match parser.current {
Token::LPar => {
let m = parser.open(diags);
expect!(LPar, "invalid syntax, expected: \'(\'", parser, diags);
loop {
match parser.current {
Token::Action
| Token::And
| Token::Assertion
| Token::Hat
| Token::Id
| Token::LBrak
| Token::LPar
| Token::NodeCreation
| Token::NodeMarker
| Token::NodeRename
| Token::Predicate
| Token::Str
| Token::Tilde => {
parser.rule_regex(diags);
break;
}
Token::RPar => break,
Token::EOF
| Token::Or
| Token::Part
| Token::Plus
| Token::RBrak
| Token::Right
| Token::Semi
| Token::Skip
| Token::Slash
| Token::Star
| Token::Start
| Token::Token => {
parser.error(diags, err![parser, "invalid syntax, expected one of: <semantic action>, \'&\', <semantic assertion>, \'^\', <identifier>, \'[\', \'(\', <node creation>, <node marker>, <node rename>, <semantic predicate>, \')\', <string literal>, \'~\'"]);
break;
}
_ => {
parser.advance_with_error(diags, err![parser, "invalid syntax, expected one of: <semantic action>, \'&\', <semantic assertion>, \'^\', <identifier>, \'[\', \'(\', <node creation>, <node marker>, <node rename>, <semantic predicate>, \')\', <string literal>, \'~\'"]);
}
}
}
expect!(RPar, "invalid syntax, expected: \')\'", parser, diags);
node_kind = Rule::Paren;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
}
Token::LBrak => {
let m = parser.open(diags);
expect!(LBrak, "invalid syntax, expected: \'[\'", parser, diags);
parser.rule_regex(diags);
expect!(RBrak, "invalid syntax, expected: \']\'", parser, diags);
node_kind = Rule::Optional;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
}
Token::Id => {
let m = parser.open(diags);
expect!(Id, "invalid syntax, expected: <identifier>", parser, diags);
node_kind = Rule::Name;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
}
Token::Str => {
let m = parser.open(diags);
expect!(
Str,
"invalid syntax, expected: <string literal>",
parser,
diags
);
node_kind = Rule::Symbol;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
}
Token::Predicate => {
let m = parser.open(diags);
expect!(
Predicate,
"invalid syntax, expected: <semantic predicate>",
parser,
diags
);
node_kind = Rule::Predicate;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
}
Token::Action => {
let m = parser.open(diags);
expect!(
Action,
"invalid syntax, expected: <semantic action>",
parser,
diags
);
node_kind = Rule::Action;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
}
Token::Assertion => {
let m = parser.open(diags);
expect!(
Assertion,
"invalid syntax, expected: <semantic assertion>",
parser,
diags
);
node_kind = Rule::Assertion;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
}
Token::NodeRename => {
let m = parser.open(diags);
expect!(
NodeRename,
"invalid syntax, expected: <node rename>",
parser,
diags
);
node_kind = Rule::NodeRename;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
}
Token::NodeMarker => {
let m = parser.open(diags);
expect!(
NodeMarker,
"invalid syntax, expected: <node marker>",
parser,
diags
);
node_kind = Rule::NodeMarker;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
}
Token::NodeCreation => {
let m = parser.open(diags);
expect!(
NodeCreation,
"invalid syntax, expected: <node creation>",
parser,
diags
);
node_kind = Rule::NodeCreation;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
}
Token::Hat => {
let m = parser.open(diags);
expect!(Hat, "invalid syntax, expected: \'^\'", parser, diags);
node_kind = Rule::NodeElision;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
}
Token::Tilde => {
let m = parser.open(diags);
expect!(Tilde, "invalid syntax, expected: \'~\'", parser, diags);
node_kind = Rule::Commit;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
}
Token::And => {
let m = parser.open(diags);
expect!(And, "invalid syntax, expected: \'&\'", parser, diags);
node_kind = Rule::Return;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
}
_ => {
parser.error(diags, err![parser, "invalid syntax, expected one of: <semantic action>, \'&\', <semantic assertion>, \'^\', <identifier>, \'[\', \'(\', <node creation>, <node marker>, <node rename>, <semantic predicate>, <string literal>, \'~\'"]);
}
}
loop {
node_kind = Rule::Postfix;
match parser.current {
Token::Star => {
let m = parser.open_before(lhs, diags);
expect!(Star, "invalid syntax, expected: \'*\'", parser, diags);
node_kind = Rule::Star;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
lhs = closed;
continue;
}
Token::Plus => {
let m = parser.open_before(lhs, diags);
expect!(Plus, "invalid syntax, expected: \'+\'", parser, diags);
node_kind = Rule::Plus;
let closed = parser.close(m, node_kind, diags);
parser.create_node(node_kind, NodeRef(closed.0), diags);
lhs = closed;
continue;
}
_ => {
break;
}
}
}
}
let lhs = self.mark(diags);
rec(self, diags, lhs);
}
}
#[allow(clippy::ptr_arg)]
pub trait ParserCallbacks<'a> {
type Diagnostic;
type Context;
fn create_tokens(
context: &mut Self::Context,
source: &'a str,
diags: &mut Vec<Self::Diagnostic>,
) -> (Vec<Token>, Vec<Span>);
fn create_diagnostic(&self, span: Span, message: String) -> Self::Diagnostic;
fn predicate_skip(&self, _token: Token) -> bool {
false
}
fn create_node_action(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_alternation(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_assertion(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_commit(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_concat(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_decl(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_error(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_file(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_name(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_node_creation(
&mut self,
_node_ref: NodeRef,
_diags: &mut Vec<Self::Diagnostic>,
) {
}
fn create_node_node_elision(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {
}
fn create_node_node_marker(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_node_rename(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_optional(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_ordered_choice(
&mut self,
_node_ref: NodeRef,
_diags: &mut Vec<Self::Diagnostic>,
) {
}
fn create_node_paren(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_part_decl(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_plus(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_postfix(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_predicate(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_regex(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_return(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_right_decl(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_rule_decl(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_skip_decl(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_star(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_start_decl(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_symbol(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_token_decl(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn create_node_token_list(&mut self, _node_ref: NodeRef, _diags: &mut Vec<Self::Diagnostic>) {}
fn predicate_decl_1(&self) -> bool;
}