Skip to content

Commit

Permalink
refactor: update ParseTree type in parser functions to remove lifetim…
Browse files Browse the repository at this point in the history
…e parameter
  • Loading branch information
jsinger67 committed Dec 15, 2024
1 parent 701cf20 commit b1263fe
Show file tree
Hide file tree
Showing 29 changed files with 94 additions and 45 deletions.
2 changes: 1 addition & 1 deletion crates/parol-ls/src/parol_ls_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1166,7 +1166,7 @@ pub fn parse<'t, T>(
input: &'t str,
file_name: T,
user_actions: &mut ParolLsGrammar,
) -> Result<ParseTree<'t>, ParolError>
) -> Result<ParseTree, ParolError>
where
T: AsRef<Path>,
{
Expand Down
2 changes: 1 addition & 1 deletion crates/parol/src/bin/parol/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl CLIListener<'_> {
impl BuildListener for CLIListener<'_> {
fn on_initial_grammar_parse(
&mut self,
syntax_tree: &ParseTree<'_>,
syntax_tree: &ParseTree,
parol_grammar: &ParolGrammar,
) -> Result<()> {
if self.verbose() {
Expand Down
2 changes: 1 addition & 1 deletion crates/parol/src/bin/parol/tools/new/lib_rs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub use {crate_name}_parser::parse;
if *tree_gen {
write!(f, "\n\n")?;
f.write_fmt(ume::ume! {
pub fn generate_tree_layout(syntax_tree: &ParseTree<'_>, input_file_name: &str) -> parol_runtime::syntree_layout::Result<()> {
pub fn generate_tree_layout(syntax_tree: &ParseTree, input_file_name: &str) -> parol_runtime::syntree_layout::Result<()> {
let mut svg_full_file_name = std::path::PathBuf::from(input_file_name);
svg_full_file_name.set_extension("svg");

Expand Down
2 changes: 1 addition & 1 deletion crates/parol/src/bin/parol/tools/new/main_rs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ use crate::{crate_name}_parser::parse;
write!(f, "\n\n")?;

f.write_fmt(ume::ume! {
fn generate_tree_layout(syntax_tree: &ParseTree<'_>, input_file_name: &str) -> parol_runtime::syntree_layout::Result<()> {
fn generate_tree_layout(syntax_tree: &ParseTree, input_file_name: &str) -> parol_runtime::syntree_layout::Result<()> {
let mut svg_full_file_name = std::path::PathBuf::from(input_file_name);
svg_full_file_name.set_extension("svg");

Expand Down
4 changes: 2 additions & 2 deletions crates/parol/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ enum State {
pub trait BuildListener {
fn on_initial_grammar_parse(
&mut self,
syntax_tree: &ParseTree<'_>,
syntax_tree: &ParseTree,
grammar: &ParolGrammar,
) -> Result<()> {
Ok(())
Expand All @@ -709,7 +709,7 @@ struct MaybeBuildListener<'l>(Option<&'l mut dyn BuildListener>);
impl BuildListener for MaybeBuildListener<'_> {
fn on_initial_grammar_parse(
&mut self,
syntax_tree: &ParseTree<'_>,
syntax_tree: &ParseTree,
grammar: &ParolGrammar,
) -> Result<()> {
if let Some(ref mut inner) = self.0 {
Expand Down
4 changes: 2 additions & 2 deletions crates/parol/src/generators/parser_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ impl std::fmt::Display for ParserData<'_> {
input: &'t str,
file_name: T,
user_actions: #user_actions,
) -> Result<ParseTree<'t>, ParolError> where T: AsRef<Path> {
) -> Result<ParseTree, ParolError> where T: AsRef<Path> {
let mut llk_parser = LLKParser::new(
#start_symbol_index,
LOOKAHEAD_AUTOMATA,
Expand Down Expand Up @@ -479,7 +479,7 @@ impl std::fmt::Display for LRParserData<'_> {
input: &'t str,
file_name: T,
user_actions: #user_actions,
) -> Result<ParseTree<'t>, ParolError> where T: AsRef<Path> {
) -> Result<ParseTree, ParolError> where T: AsRef<Path> {
let mut lr_parser = LRParser::new(
#start_symbol_index,
&PARSE_TABLE,
Expand Down
2 changes: 1 addition & 1 deletion crates/parol/src/parser/parol_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,7 @@ pub fn parse<'t, T>(
input: &'t str,
file_name: T,
user_actions: &mut ParolGrammar<'t>,
) -> Result<ParseTree<'t>, ParolError>
) -> Result<ParseTree, ParolError>
where
T: AsRef<Path>,
{
Expand Down
2 changes: 1 addition & 1 deletion crates/parol/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ pub fn obtain_grammar_config_from_string(input: &str, verbose: bool) -> Result<G
///
/// Utility function for generating tree layouts
///
pub fn generate_tree_layout<T>(syntax_tree: &ParseTree<'_>, input_file_name: T) -> Result<()>
pub fn generate_tree_layout<T>(syntax_tree: &ParseTree, input_file_name: T) -> Result<()>
where
T: AsRef<Path>,
{
Expand Down
14 changes: 14 additions & 0 deletions crates/parol_runtime/src/lexer/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,20 @@ pub struct PTToken {
pub token_number: TokenNumber,
}

impl PTToken {
/// Calculate the length of the token
#[inline]
pub fn len(&self) -> usize {
self.end.saturating_sub(self.start)
}

/// Returns true if the token is empty
#[inline]
pub fn is_empty(&self) -> bool {
self.start >= self.end
}
}

impl From<&Token<'_>> for PTToken {
fn from(token: &Token<'_>) -> Self {
Self {
Expand Down
14 changes: 7 additions & 7 deletions crates/parol_runtime/src/lr_parser/parse_tree.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{convert::TryFrom, fmt::Display};

use crate::{ParseTreeType, Token};
use crate::{parser::parse_tree_type::SynTree, ParseTreeType, Token};
use syntree::{Builder, Tree};

/// Parse tree representation.
Expand Down Expand Up @@ -40,31 +40,31 @@ impl Display for LRParseTree<'_> {
// parse tree is built during parsing, it is unlikely that the parse tree is too deep.
// Otherwise, we need to convert this function to an iterative function.
fn build_tree<'t>(
builder: &mut Builder<ParseTreeType<'t>, u32, usize>,
builder: &mut Builder<SynTree, u32, usize>,
parse_tree: LRParseTree<'t>,
) -> Result<(), syntree::Error> {
match parse_tree {
LRParseTree::Terminal(token) => {
let len = token.text().len();
builder.token(ParseTreeType::T(token), len)?;
let len = token.location.len();
builder.token(SynTree::Terminal((&token).into()), len)?;
}
LRParseTree::NonTerminal(name, children) => {
builder.open(ParseTreeType::N(name))?;
builder.open(SynTree::NonTerminal(name))?;
if let Some(children) = children {
for child in children {
build_tree(builder, child)?;
}
}
builder.close()?;
}
}
};
Ok(())
}

// Convert a parse tree to a syntree tree.
// Since syntree must be built from the root, we use the LRParseTree during parsing and convert it
// to a syntree tree afterwards.
impl<'t> TryFrom<LRParseTree<'t>> for Tree<ParseTreeType<'t>, u32, usize> {
impl<'t> TryFrom<LRParseTree<'t>> for Tree<SynTree, u32, usize> {
type Error = syntree::Error;

fn try_from(parse_tree: LRParseTree<'t>) -> Result<Self, Self::Error> {
Expand Down
10 changes: 6 additions & 4 deletions crates/parol_runtime/src/lr_parser/parser_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ use core::str;
use std::{cell::RefCell, collections::BTreeSet, convert::TryInto, rc::Rc};

use log::trace;
use syntree::Tree;

use crate::{
parser::parser_types::TreeBuilder, FileSource, LRParseTree, NonTerminalIndex, ParolError,
ParseTree, ParseTreeStack, ParseTreeType, ParserError, ProductionIndex, Result, SyntaxError,
TerminalIndex, TokenStream, TokenVec, UnexpectedToken, UserActionsTrait,
parser::{parse_tree_type::SynTree, parser_types::TreeBuilder},
FileSource, LRParseTree, NonTerminalIndex, ParolError, ParseTreeStack, ParseTreeType,
ParserError, ProductionIndex, Result, SyntaxError, TerminalIndex, TokenStream, TokenVec,
UnexpectedToken, UserActionsTrait,
};

/// The type of the index of a LR action in the parse table's actions array.
Expand Down Expand Up @@ -308,7 +310,7 @@ impl<'t> LRParser<'t> {
&mut self,
stream: TokenStream<'t>,
user_actions: &'u mut dyn UserActionsTrait<'t>,
) -> Result<ParseTree<'t>> {
) -> Result<Tree<SynTree, u32, usize>> {
let stream = Rc::new(RefCell::new(stream));

// Initialize the parse stack and the parse tree stack.
Expand Down
33 changes: 32 additions & 1 deletion crates/parol_runtime/src/parser/parse_tree_type.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{ParserError, Token};
use crate::{lexer::token::PTToken, ParserError, Token};

use std::fmt::{Display, Formatter};
use syntree_layout::Visualize;
Expand Down Expand Up @@ -70,3 +70,34 @@ impl Display for ParseTreeType<'_> {
}
}
}

/// Parse tree representation.
/// It is uses to build the syntree tree. The syntree tree expects the tree type to be Copy.
#[derive(Debug, Clone, Copy)]
pub enum SynTree {
/// A terminal node
Terminal(PTToken),
/// A non-terminal node
NonTerminal(&'static str),
}

impl Visualize for SynTree {
fn visualize(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SynTree::Terminal(t) => write!(f, "{}", t),
SynTree::NonTerminal(n) => write!(f, "{}", n),
}
}
fn emphasize(&self) -> bool {
matches!(self, SynTree::Terminal(_))
}
}

impl Display for SynTree {
fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
match self {
SynTree::Terminal(t) => write!(f, "T({})", t),
SynTree::NonTerminal(n) => write!(f, "N({})", n),
}
}
}
16 changes: 9 additions & 7 deletions crates/parol_runtime/src/parser/parser_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use log::trace;
use std::{cell::RefCell, cmp::Ord, rc::Rc};
use syntree::{Builder, Tree};

use super::parse_tree_type::SynTree;

///
/// The type that contains all data to process a production within the parser.
///
Expand Down Expand Up @@ -52,10 +54,10 @@ impl Production {
}

/// The type used for the parse tree
pub type ParseTree<'t> = Tree<ParseTreeType<'t>, u32, usize>;
pub type ParseTree = Tree<SynTree, u32, usize>;

/// The parse tree builder type
pub(crate) type TreeBuilder<'t> = Builder<ParseTreeType<'t>, u32, usize>;
pub(crate) type TreeBuilder = Builder<SynTree, u32, usize>;

///
/// The actual LLK parser.
Expand Down Expand Up @@ -203,7 +205,7 @@ impl<'t> LLKParser<'t> {

fn push_production(
&mut self,
tree_builder: &mut TreeBuilder<'t>,
tree_builder: &mut TreeBuilder,
prod_num: ProductionIndex,
) -> Result<()> {
self.parser_stack.stack.push(ParseType::E(prod_num));
Expand All @@ -214,7 +216,7 @@ impl<'t> LLKParser<'t> {
// Open a 'production entry' node in the tree
if !self.trim_parse_tree {
tree_builder
.open(ParseTreeType::N(
.open(SynTree::NonTerminal(
self.non_terminal_names[self.productions[prod_num].lhs],
))
.map_err(|source| ParserError::TreeError { source })?;
Expand All @@ -238,7 +240,7 @@ impl<'t> LLKParser<'t> {

fn process_item_stack<'u>(
&mut self,
tree_builder: &mut TreeBuilder<'t>,
tree_builder: &mut TreeBuilder,
prod_num: ProductionIndex,
user_actions: &'u mut dyn UserActionsTrait<'t>,
) -> Result<()> {
Expand Down Expand Up @@ -318,7 +320,7 @@ impl<'t> LLKParser<'t> {
&mut self,
stream: TokenStream<'t>,
user_actions: &'u mut dyn UserActionsTrait<'t>,
) -> Result<ParseTree<'t>> {
) -> Result<Tree<SynTree, u32, usize>> {
let stream = Rc::new(RefCell::new(stream));
let prod_num = match self.predict_production(self.start_symbol_index, stream.clone()) {
Ok(prod_num) => prod_num,
Expand Down Expand Up @@ -347,7 +349,7 @@ impl<'t> LLKParser<'t> {
self.parser_stack.stack.pop();
if !self.trim_parse_tree {
tree_builder
.token(ParseTreeType::T(token.clone()), 1)
.token(SynTree::Terminal((&token).into()), 1)
.map_err(|source| ParserError::TreeError { source })?;
}
self.parse_tree_stack.push(ParseTreeType::T(token));
Expand Down
2 changes: 1 addition & 1 deletion examples/basic_interpreter/basic_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,7 @@ pub fn parse<'t, T>(
input: &'t str,
file_name: T,
user_actions: &mut BasicGrammar<'t>,
) -> Result<ParseTree<'t>, ParolError>
) -> Result<ParseTree, ParolError>
where
T: AsRef<Path>,
{
Expand Down
2 changes: 1 addition & 1 deletion examples/basic_interpreter/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fn main() -> anyhow::Result<std::process::ExitCode> {
}
}

fn generate_tree_layout(syntax_tree: &ParseTree<'_>, input_file_name: &str) -> Result<()> {
fn generate_tree_layout(syntax_tree: &ParseTree, input_file_name: &str) -> Result<()> {
let mut svg_full_file_name = std::path::PathBuf::from(input_file_name);
svg_full_file_name.set_extension("svg");

Expand Down
2 changes: 1 addition & 1 deletion examples/boolean_parser/boolean_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ pub fn parse<'t, T>(
input: &'t str,
file_name: T,
user_actions: &mut BooleanGrammar<'t>,
) -> Result<ParseTree<'t>, ParolError>
) -> Result<ParseTree, ParolError>
where
T: AsRef<Path>,
{
Expand Down
2 changes: 1 addition & 1 deletion examples/calc/calc_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,7 @@ pub fn parse<'t, T>(
input: &'t str,
file_name: T,
user_actions: &mut CalcGrammar<'t>,
) -> Result<ParseTree<'t>, ParolError>
) -> Result<ParseTree, ParolError>
where
T: AsRef<Path>,
{
Expand Down
2 changes: 1 addition & 1 deletion examples/calc_lr/calc_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1486,7 +1486,7 @@ pub fn parse<'t, T>(
input: &'t str,
file_name: T,
user_actions: &mut CalcGrammar<'t>,
) -> Result<ParseTree<'t>, ParolError>
) -> Result<ParseTree, ParolError>
where
T: AsRef<Path>,
{
Expand Down
2 changes: 1 addition & 1 deletion examples/json_parser/json_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ pub fn parse<'t, T>(
input: &'t str,
file_name: T,
user_actions: &mut JsonGrammar<'t>,
) -> Result<ParseTree<'t>, ParolError>
) -> Result<ParseTree, ParolError>
where
T: AsRef<Path>,
{
Expand Down
2 changes: 1 addition & 1 deletion examples/keywords/keywords_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ pub fn parse<'t, T>(
input: &'t str,
file_name: T,
user_actions: &mut KeywordsGrammar<'t>,
) -> Result<ParseTree<'t>, ParolError>
) -> Result<ParseTree, ParolError>
where
T: AsRef<Path>,
{
Expand Down
2 changes: 1 addition & 1 deletion examples/keywords2/keywords_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ pub fn parse<'t, T>(
input: &'t str,
file_name: T,
user_actions: &mut KeywordsGrammar<'t>,
) -> Result<ParseTree<'t>, ParolError>
) -> Result<ParseTree, ParolError>
where
T: AsRef<Path>,
{
Expand Down
2 changes: 1 addition & 1 deletion examples/list/list_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ pub fn parse<'t, T>(
input: &'t str,
file_name: T,
user_actions: &mut ListGrammar,
) -> Result<ParseTree<'t>, ParolError>
) -> Result<ParseTree, ParolError>
where
T: AsRef<Path>,
{
Expand Down
2 changes: 1 addition & 1 deletion examples/list_lr/list_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ pub fn parse<'t, T>(
input: &'t str,
file_name: T,
user_actions: &mut ListGrammar,
) -> Result<ParseTree<'t>, ParolError>
) -> Result<ParseTree, ParolError>
where
T: AsRef<Path>,
{
Expand Down
2 changes: 1 addition & 1 deletion examples/oberon2/oberon2_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2872,7 +2872,7 @@ pub fn parse<'t, T>(
input: &'t str,
file_name: T,
user_actions: &mut Oberon2Grammar<'t>,
) -> Result<ParseTree<'t>, ParolError>
) -> Result<ParseTree, ParolError>
where
T: AsRef<Path>,
{
Expand Down
2 changes: 1 addition & 1 deletion examples/oberon_0/oberon_0_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1444,7 +1444,7 @@ pub fn parse<'t, T>(
input: &'t str,
file_name: T,
user_actions: &mut Oberon0Grammar<'t>,
) -> Result<ParseTree<'t>, ParolError>
) -> Result<ParseTree, ParolError>
where
T: AsRef<Path>,
{
Expand Down
Loading

0 comments on commit b1263fe

Please sign in to comment.