use std::borrow::Borrow;
use std::cell::{Cell, RefCell};
use std::marker::PhantomData;
use std::ops::{CoerceUnsized, Deref, DerefMut};
use std::rc::Rc;
use std::sync::Arc;
use crate::atn::ATN;
use crate::atn_simulator::IATNSimulator;
use crate::error_listener::{ConsoleErrorListener, ErrorListener, ProxyErrorListener};
use crate::error_strategy::ErrorStrategy;
use crate::errors::ANTLRError;
use crate::interval_set::IntervalSet;
use crate::parser_atn_simulator::ParserATNSimulator;
use crate::parser_rule_context::ParserRuleContext;
use crate::recognizer::{Actions, Recognizer};
use crate::rule_context::{states_stack, CustomRuleContext, RuleContext};
use crate::token::{Token, TOKEN_EOF};
use crate::token_factory::{TokenAware, TokenFactory};
use crate::token_stream::TokenStream;
use crate::tree::{ErrorNode, Listenable, ParseTreeListener, TerminalNode};
use crate::vocabulary::Vocabulary;
use better_any::{Tid, TidAble};
#[allow(missing_docs)]
pub trait Parser<'input>: Recognizer<'input> {
fn get_interpreter(&self) -> &ParserATNSimulator;
fn get_token_factory(&self) -> &'input Self::TF;
fn get_parser_rule_context(&self) -> &Rc<<Self::Node as ParserNodeType<'input>>::Type>;
fn consume(&mut self, err_handler: &mut impl ErrorStrategy<'input, Self>)
where
Self: Sized;
fn precpred(
&self,
localctx: Option<&<Self::Node as ParserNodeType<'input>>::Type>,
precedence: isize,
) -> bool;
fn get_input_stream_mut(&mut self) -> &mut dyn TokenStream<'input, TF = Self::TF>;
fn get_input_stream(&self) -> &dyn TokenStream<'input, TF = Self::TF>;
fn get_current_token(&self) -> &<Self::TF as TokenFactory<'input>>::Tok;
fn get_expected_tokens(&self) -> IntervalSet;
fn add_error_listener(&mut self, listener: Box<dyn ErrorListener<'input, Self>>)
where
Self: Sized;
fn notify_error_listeners(
&self,
msg: String,
offending_token: Option<isize>,
err: Option<&ANTLRError>,
);
fn get_error_lister_dispatch<'a>(&'a self) -> Box<dyn ErrorListener<'input, Self> + 'a>
where
Self: Sized;
fn is_expected_token(&self, symbol: isize) -> bool;
fn get_precedence(&self) -> isize;
fn get_state(&self) -> isize;
fn set_state(&mut self, v: isize);
fn get_rule_invocation_stack(&self) -> Vec<String>;
}
pub trait ParserNodeType<'input>: TidAble<'input> + Sized {
type TF: TokenFactory<'input> + 'input;
type Type: ?Sized + ParserRuleContext<'input, Ctx = Self, TF = Self::TF> + 'input;
}
#[derive(Tid)]
pub struct BaseParser<
'input,
Ext: 'static,
I: TokenStream<'input>,
Ctx: ParserNodeType<'input, TF = I::TF>,
T: ParseTreeListener<'input, Ctx> + ?Sized = dyn ParseTreeListener<'input, Ctx>,
> {
interp: Arc<ParserATNSimulator>,
pub ctx: Option<Rc<Ctx::Type>>,
pub build_parse_trees: bool,
pub matched_eof: bool,
state: isize,
pub input: I,
precedence_stack: Vec<isize>,
parse_listeners: Vec<Box<T>>,
_syntax_errors: Cell<isize>,
error_listeners: RefCell<Vec<Box<dyn ErrorListener<'input, Self>>>>,
ext: Ext,
pd: PhantomData<fn() -> &'input str>,
}
impl<'input, Ext, I, Ctx, T> Deref for BaseParser<'input, Ext, I, Ctx, T>
where
Ext: ParserRecog<'input, Self> + 'static,
I: TokenStream<'input>,
Ctx: ParserNodeType<'input, TF = I::TF>,
T: ParseTreeListener<'input, Ctx> + ?Sized,
{
type Target = Ext;
fn deref(&self) -> &Self::Target { &self.ext }
}
impl<'input, Ext, I, Ctx, T> DerefMut for BaseParser<'input, Ext, I, Ctx, T>
where
Ext: ParserRecog<'input, Self> + 'static,
I: TokenStream<'input>,
Ctx: ParserNodeType<'input, TF = I::TF>,
T: ParseTreeListener<'input, Ctx> + ?Sized,
{
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.ext }
}
pub trait ParserRecog<'a, P: Recognizer<'a>>: Actions<'a, P> {}
impl<'input, Ext, I, Ctx, T> Recognizer<'input> for BaseParser<'input, Ext, I, Ctx, T>
where
Ext: ParserRecog<'input, Self> + 'static,
I: TokenStream<'input>,
Ctx: ParserNodeType<'input, TF = I::TF>,
T: ParseTreeListener<'input, Ctx> + ?Sized,
{
type Node = Ctx;
fn sempred(
&mut self,
localctx: Option<&Ctx::Type>,
rule_index: isize,
action_index: isize,
) -> bool {
<Ext as Actions<'input, Self>>::sempred(localctx, rule_index, action_index, self)
}
fn get_rule_names(&self) -> &[&str] { self.ext.get_rule_names() }
fn get_vocabulary(&self) -> &dyn Vocabulary { self.ext.get_vocabulary() }
fn get_grammar_file_name(&self) -> &str { self.ext.get_grammar_file_name() }
fn get_atn(&self) -> &ATN { self.interp.atn() }
}
impl<'input, Ext, I, Ctx, T> TokenAware<'input> for BaseParser<'input, Ext, I, Ctx, T>
where
Ext: ParserRecog<'input, Self> + 'static,
I: TokenStream<'input>,
Ctx: ParserNodeType<'input, TF = I::TF>,
T: ParseTreeListener<'input, Ctx> + ?Sized,
{
type TF = I::TF;
}
impl<'input, Ext, I, Ctx, T> Parser<'input> for BaseParser<'input, Ext, I, Ctx, T>
where
Ext: ParserRecog<'input, Self> + 'static,
I: TokenStream<'input>,
Ctx: ParserNodeType<'input, TF = I::TF>,
T: ParseTreeListener<'input, Ctx> + ?Sized,
Ctx::Type: Listenable<T>,
Rc<TerminalNode<'input, Ctx>>: CoerceUnsized<Rc<Ctx::Type>>,
Rc<ErrorNode<'input, Ctx>>: CoerceUnsized<Rc<Ctx::Type>>,
{
fn get_interpreter(&self) -> &ParserATNSimulator { self.interp.as_ref() }
fn get_token_factory(&self) -> &'input Self::TF {
self.input.get_token_source().get_token_factory()
}
#[inline(always)]
fn get_parser_rule_context(&self) -> &Rc<Ctx::Type> { self.ctx.as_ref().unwrap() }
fn consume(&mut self, err_handler: &mut impl ErrorStrategy<'input, Self>) {
let o = self.get_current_token().clone();
if o.borrow().get_token_type() != TOKEN_EOF {
self.input.consume();
}
if self.build_parse_trees || !self.parse_listeners.is_empty() {
if err_handler.in_error_recovery_mode(self) {
let node: Rc<ErrorNode<'_, Ctx>> = self.create_error_node(o.clone());
self.ctx
.as_deref()
.unwrap()
.add_child(node.clone() as Rc<Ctx::Type>);
for listener in &mut self.parse_listeners {
listener.visit_error_node(&*node)
}
} else {
let node: Rc<TerminalNode<'_, Ctx>> = self.create_token_node(o.clone());
self.ctx
.as_deref()
.unwrap()
.add_child(node.clone() as Rc<Ctx::Type>);
for listener in &mut self.parse_listeners {
listener.visit_terminal(&*node)
}
}
}
}
fn precpred(&self, _localctx: Option<&Ctx::Type>, precedence: isize) -> bool {
precedence >= self.get_precedence()
}
fn get_input_stream_mut(&mut self) -> &mut dyn TokenStream<'input, TF = Self::TF> {
&mut self.input
}
fn get_input_stream(&self) -> &dyn TokenStream<'input, TF = Self::TF> { &self.input }
#[inline]
fn get_current_token(&self) -> &<Self::TF as TokenFactory<'input>>::Tok {
self.input.get(self.input.index())
}
fn get_expected_tokens(&self) -> IntervalSet {
let states_stack = states_stack(self.ctx.as_ref().unwrap().clone());
self.interp
.atn()
.get_expected_tokens(self.state, states_stack)
}
fn add_error_listener(&mut self, listener: Box<dyn ErrorListener<'input, Self>>) {
self.error_listeners.borrow_mut().push(listener)
}
fn notify_error_listeners(
&self,
msg: String,
offending_token: Option<isize>,
err: Option<&ANTLRError>,
) {
self._syntax_errors.update(|it| it + 1);
let offending_token: Option<&_> = match offending_token {
None => Some(self.get_current_token().borrow()),
Some(x) => Some(self.input.get(x).borrow()),
};
let line = offending_token.map(|x| x.get_line()).unwrap_or(-1);
let column = offending_token.map(|x| x.get_column()).unwrap_or(-1);
for listener in self.error_listeners.borrow().iter() {
listener.syntax_error(self, offending_token, line, column, &msg, err)
}
}
fn get_error_lister_dispatch<'a>(&'a self) -> Box<dyn ErrorListener<'input, Self> + 'a> {
Box::new(ProxyErrorListener {
delegates: self.error_listeners.borrow(),
})
}
fn is_expected_token(&self, _symbol: isize) -> bool { unimplemented!() }
fn get_precedence(&self) -> isize { *self.precedence_stack.last().unwrap_or(&-1) }
#[inline(always)]
fn get_state(&self) -> isize { self.state }
#[inline(always)]
fn set_state(&mut self, v: isize) { self.state = v; }
fn get_rule_invocation_stack(&self) -> Vec<String> {
let mut vec = Vec::new();
let rule_names = self.get_rule_names();
let mut ctx = self.get_parser_rule_context().clone();
loop {
let rule_index = ctx.get_rule_index();
vec.push(rule_names.get(rule_index).unwrap_or(&"n/a").to_string());
ctx = if let Some(parent) = ctx.get_parent_ctx() {
parent
} else {
break;
}
}
vec
}
}
#[allow(missing_docs)]
impl<'input, Ext, I, Ctx, T> BaseParser<'input, Ext, I, Ctx, T>
where
Ext: ParserRecog<'input, Self> + 'static,
I: TokenStream<'input>,
Ctx: ParserNodeType<'input, TF = I::TF>,
T: ParseTreeListener<'input, Ctx> + ?Sized,
Ctx::Type: Listenable<T>,
Rc<TerminalNode<'input, Ctx>>: CoerceUnsized<Rc<Ctx::Type>>,
Rc<ErrorNode<'input, Ctx>>: CoerceUnsized<Rc<Ctx::Type>>,
{
pub fn new_base_parser(input: I, interpreter: Arc<ParserATNSimulator>, ext: Ext) -> Self {
Self {
interp: interpreter,
ctx: None,
build_parse_trees: true,
matched_eof: false,
state: -1,
input,
precedence_stack: vec![0],
parse_listeners: vec![],
_syntax_errors: Cell::new(0),
error_listeners: RefCell::new(vec![Box::new(ConsoleErrorListener {})]),
ext,
pd: PhantomData,
}
}
#[inline]
pub fn match_token(
&mut self,
ttype: isize,
err_handler: &mut impl ErrorStrategy<'input, Self>,
) -> Result<<I::TF as TokenFactory<'input>>::Tok, ANTLRError> {
let mut token = self.get_current_token().clone();
if token.borrow().get_token_type() == ttype {
if ttype == TOKEN_EOF {
self.matched_eof = true;
}
err_handler.report_match(self);
self.consume(err_handler);
} else {
token = err_handler.recover_inline(self)?;
if self.build_parse_trees && token.borrow().get_token_index() == -1 {
self.ctx
.as_ref()
.unwrap()
.add_child(self.create_error_node(token.clone()) as Rc<Ctx::Type>);
}
}
return Ok(token);
}
#[inline]
pub fn match_wildcard(
&mut self,
err_handler: &mut impl ErrorStrategy<'input, Self>,
) -> Result<<I::TF as TokenFactory<'input>>::Tok, ANTLRError> {
let mut t = self.get_current_token().clone();
if t.borrow().get_token_type() > 0 {
err_handler.report_match(self);
self.consume(err_handler);
} else {
t = err_handler.recover_inline(self)?;
if self.build_parse_trees && t.borrow().get_token_index() == -1 {
self.ctx
.as_ref()
.unwrap()
.add_child(self.create_error_node(t.clone()) as Rc<Ctx::Type>);
}
}
return Ok(t);
}
pub fn add_parse_listener<L>(&mut self, listener: Box<L>) -> ListenerId<L>
where
Box<L>: CoerceUnsized<Box<T>>,
{
let id = ListenerId::new(&listener);
self.parse_listeners.push(listener);
id
}
pub fn remove_parse_listener<L>(&mut self, listener_id: ListenerId<L>) -> Box<L>
where
Box<L>: CoerceUnsized<Box<T>>,
{
let index = self
.parse_listeners
.iter()
.position(|it| ListenerId::new(it).actual_id == listener_id.actual_id)
.expect("listener not found");
unsafe { listener_id.into_listener(self.parse_listeners.remove(index)) }
}
pub fn remove_parse_listeners(&mut self) { self.parse_listeners.clear() }
pub fn trigger_enter_rule_event(&mut self) {
let ctx = self.ctx.as_deref().unwrap();
for listener in self.parse_listeners.iter_mut() {
ctx.enter(listener);
}
}
pub fn trigger_exit_rule_event(&mut self) {
let ctx = self.ctx.as_deref().unwrap();
for listener in self.parse_listeners.iter_mut().rev() {
ctx.exit(listener);
}
}
fn add_context_to_parse_tree(&mut self) {
let parent = self.ctx.as_ref().unwrap().get_parent_ctx();
if let Some(parent) = parent {
parent.add_child(self.ctx.clone().unwrap())
}
}
#[inline]
pub fn enter_rule(&mut self, localctx: Rc<Ctx::Type>, state: isize, _rule_index: usize) {
self.set_state(state);
localctx.set_start(self.input.lt(1).cloned());
self.ctx = Some(localctx);
if self.build_parse_trees {
self.add_context_to_parse_tree()
}
}
#[inline]
pub fn exit_rule(&mut self) {
if self.matched_eof {
self.ctx
.as_ref()
.unwrap()
.set_stop(self.input.lt(1).cloned())
} else {
self.ctx
.as_ref()
.unwrap()
.set_stop(self.input.lt(-1).cloned())
}
self.trigger_exit_rule_event();
self.set_state(self.get_parser_rule_context().get_invoking_state());
let parent = self.ctx.as_ref().unwrap().get_parent_ctx();
self.ctx = parent;
}
#[inline]
pub fn enter_outer_alt(&mut self, new_ctx: Option<Rc<Ctx::Type>>, alt_num: isize) {
if let Some(new_ctx) = new_ctx {
new_ctx.set_alt_number(alt_num);
let ctx = self.ctx.as_ref().unwrap();
if self.build_parse_trees && self.ctx.is_some() && !Rc::ptr_eq(&new_ctx, ctx) {
if let Some(parent) = ctx.get_parent_ctx() {
parent.remove_last_child();
parent.add_child(new_ctx.clone())
}
}
self.ctx = Some(new_ctx);
}
self.trigger_enter_rule_event();
}
pub fn enter_recursion_rule(
&mut self,
localctx: Rc<Ctx::Type>,
state: isize,
_rule_index: usize,
precedence: isize,
) {
self.set_state(state);
self.precedence_stack.push(precedence);
localctx.set_start(self.input.lt(1).cloned());
self.ctx = Some(localctx);
}
pub fn push_new_recursion_context(
&mut self,
localctx: Rc<Ctx::Type>,
state: isize,
_rule_index: usize,
) {
let prev = self.ctx.take().unwrap();
prev.set_parent(&Some(localctx.clone()));
prev.set_invoking_state(state);
prev.set_stop(self.input.lt(-1).cloned());
localctx.set_start(Some(prev.start_mut().clone()));
self.ctx = Some(localctx);
if self.build_parse_trees {
self.ctx.as_ref().unwrap().add_child(prev);
}
self.trigger_enter_rule_event();
}
pub fn unroll_recursion_context(&mut self, parent_ctx: Option<Rc<Ctx::Type>>) {
self.precedence_stack.pop();
let retctx = self.ctx.clone().unwrap();
retctx.set_stop(self.input.lt(-1).cloned());
if !self.parse_listeners.is_empty() {
while self.ctx.as_ref().map(|x| Rc::as_ptr(x))
!= parent_ctx.as_ref().map(|x| Rc::as_ptr(x))
{
self.trigger_exit_rule_event();
self.ctx = self.ctx.as_ref().unwrap().get_parent_ctx()
}
} else {
self.ctx = parent_ctx;
}
retctx.set_parent(&self.ctx);
if self.build_parse_trees && self.ctx.is_some() {
self.ctx.as_ref().unwrap().add_child(retctx);
}
}
fn create_token_node(
&self,
token: <I::TF as TokenFactory<'input>>::Tok,
) -> Rc<TerminalNode<'input, Ctx>> {
TerminalNode::new(token).into()
}
fn create_error_node(
&self,
token: <I::TF as TokenFactory<'input>>::Tok,
) -> Rc<ErrorNode<'input, Ctx>> {
ErrorNode::new(token).into()
}
pub fn dump_dfa(&self) {
let mut seen_one = false;
for dfa in self.interp.decision_to_dfa() {
let dfa = dfa.read();
if dfa.states.len() > 1 + (dfa.is_precedence_dfa() as usize) {
if seen_one {
println!()
}
println!("Decision {}:", dfa.decision);
print!("{}", dfa.to_string(self.get_vocabulary()));
seen_one = true;
}
}
}
}
#[derive(Debug)]
pub struct ListenerId<T: ?Sized> {
pub(crate) actual_id: usize,
phantom: PhantomData<fn() -> T>,
}
impl<T: ?Sized> ListenerId<T> {
fn new(listener: &Box<T>) -> ListenerId<T> {
ListenerId {
actual_id: listener.as_ref() as *const T as *const () as usize,
phantom: Default::default(),
}
}
}
impl<T> ListenerId<T> {
unsafe fn into_listener<U: ?Sized>(self, boxed: Box<U>) -> Box<T> {
Box::from_raw(Box::into_raw(boxed) as *mut T)
}
}