Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean-up parser codegen and allow constructing DSL v1 model directly #656

Merged
merged 5 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 18 additions & 53 deletions crates/codegen/grammar/src/dsl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ macro_rules! slang_grammar {
slang_grammar_top_level_clause! { $($idents)+ $value }
)*

pub trait GrammarConstructor {
fn new() -> std::rc::Rc<$crate::Grammar>;
pub trait GrammarConstructorDslV1 {
fn from_dsl_v1() -> std::rc::Rc<$crate::Grammar>;
}

impl GrammarConstructor for $crate::Grammar {
fn new() -> std::rc::Rc<$crate::Grammar> {
impl GrammarConstructorDslV1 for $crate::Grammar {
fn from_dsl_v1() -> std::rc::Rc<$crate::Grammar> {
let name = slang_grammar_top_level_config! {
name
$( $($idents)+ = $value ; )*
Expand Down Expand Up @@ -180,7 +180,6 @@ macro_rules! slang_grammar_definition {
}

impl $name {
const SOURCE_LOCATION: $crate::SourceLocation = slang_location!();
const NAME: &str = stringify!($name);
fn instance() -> $crate::$trait_ref {
use ::std::rc::Rc;
Expand All @@ -197,9 +196,6 @@ macro_rules! slang_grammar_definition {
fn name(&self) -> &'static str {
Self::NAME
}
fn source_location(&self) -> $crate::SourceLocation {
Self::SOURCE_LOCATION
}
fn node(&self) -> &$crate::$node_type {
&self.node.get_or_init(|| $dsl_macro!($value))
}
Expand Down Expand Up @@ -241,41 +237,26 @@ macro_rules! slang_grammar_register_definitions {

}

#[macro_export]
macro_rules! slang_location {
// Meaningless in macro_rules! because the locations are all wrong.
() => {
$crate::SourceLocation {
file: file!(),
line: line!(),
column: column!(),
}
};
}

#[macro_export]
macro_rules! slang_parser {

( $x:ident ) => {
($x::instance(), slang_location!()).into()
$x::instance().into()
};

(( $x:tt ? )) => {
$crate::ParserDefinitionNode::Optional(
Box::new(slang_parser!($x)) ,
slang_location!()
Box::new(slang_parser!($x))
)
};
(( $x:tt * )) => {
$crate::ParserDefinitionNode::ZeroOrMore(
Box::new(slang_parser!($x)) ,
slang_location!()
Box::new(slang_parser!($x)),
)
};
(( $x:tt + )) => {
$crate::ParserDefinitionNode::OneOrMore(
Box::new(slang_parser!($x)) ,
slang_location!()
Box::new(slang_parser!($x)),
)
};

Expand All @@ -284,28 +265,24 @@ macro_rules! slang_parser {
Box::new(slang_parser!($o)),
Box::new(slang_parser!($b)),
Box::new(slang_parser!($c)),
slang_location!()
)
};
(( $b:tt terminated by $t:tt )) => {
$crate::ParserDefinitionNode::TerminatedBy(
Box::new(slang_parser!($b)),
Box::new(slang_parser!($t)),
slang_location!()
)
};
(( $b:tt separated by $s:tt )) => {
$crate::ParserDefinitionNode::SeparatedBy(
Box::new(slang_parser!($b)),
Box::new(slang_parser!($s)),
slang_location!()
)
};

(( $first:tt | $($rest:tt)|+ )) => {
$crate::ParserDefinitionNode::Choice(
vec![slang_parser!($first), $(slang_parser!($rest)),+],
slang_location!()
)
};

Expand All @@ -316,7 +293,6 @@ macro_rules! slang_parser {
(( $($rest:tt)+ )) => {
$crate::ParserDefinitionNode::Sequence(
vec![$(slang_parser!($rest)),+],
slang_location!()
)
};

Expand All @@ -333,7 +309,6 @@ macro_rules! slang_precedence_parser {
$crate::PrecedenceParserDefinitionNode {
primary_expression: Box::new(slang_parser!($primary)),
operators: slang_precedence_parser_operators!([ [] [] ] $($operators)+),
source_location: slang_location!()
}
};

Expand Down Expand Up @@ -420,8 +395,8 @@ macro_rules! slang_precedence_parser_operators {
$($version,)*
{
$crate::VersionQualityRange {
from: (semver::Version::parse($from).unwrap(), slang_location!()),
quality: ($crate::VersionQuality::Introduced, slang_location!())
from: semver::Version::parse($from).unwrap(),
quality: $crate::VersionQuality::Introduced
}
}
]
Expand All @@ -436,8 +411,8 @@ macro_rules! slang_precedence_parser_operators {
$($version,)*
{
$crate::VersionQualityRange {
from: (semver::Version::parse($from).unwrap(), slang_location!()),
quality: ($crate::VersionQuality::Removed, slang_location!())
from: semver::Version::parse($from).unwrap(),
quality: $crate::VersionQuality::Removed
}
}
]
Expand All @@ -456,58 +431,50 @@ macro_rules! slang_scanner {
( $x:literal ) => {
$crate::ScannerDefinitionNode::Literal(
$x.to_string(),
slang_location!()
)
};
( $x:ident ) => {
($x::instance(), slang_location!()).into()
($x::instance()).into()
};

(( ! $x:literal )) => {
$crate::ScannerDefinitionNode::NoneOf(
$x.to_string(),
slang_location!()
)
};
(( $x:tt ? )) => {
$crate::ScannerDefinitionNode::Optional(
Box::new(slang_scanner!($x)) ,
slang_location!()
Box::new(slang_scanner!($x)),
)
};
(( $x:tt * )) => {
$crate::ScannerDefinitionNode::ZeroOrMore(
Box::new(slang_scanner!($x)) ,
slang_location!()
Box::new(slang_scanner!($x)),
)
};
(( $x:tt + )) => {
$crate::ScannerDefinitionNode::OneOrMore(
Box::new(slang_scanner!($x)) ,
slang_location!()
Box::new(slang_scanner!($x)),
)
};

(( $x:literal .. $y:literal )) => {
$crate::ScannerDefinitionNode::CharRange(
$x, $y,
slang_location!()
)
};

(( $b:tt not followed by $nla:tt )) => {
$crate::ScannerDefinitionNode::NotFollowedBy(
Box::new(slang_scanner!($b)),
Box::new(slang_scanner!($nla)),
slang_location!()
)
};


(( $first:tt | $($rest:tt)|+ )) => {
$crate::ScannerDefinitionNode::Choice(
vec![slang_scanner!($first), $(slang_scanner!($rest)),+],
slang_location!()
)
};

Expand All @@ -518,7 +485,6 @@ macro_rules! slang_scanner {
(( $($rest:tt)+ )) => {
$crate::ScannerDefinitionNode::Sequence(
vec![$(slang_scanner!($rest)),+],
slang_location!()
)
};

Expand Down Expand Up @@ -552,8 +518,8 @@ macro_rules! slang_dsl_versioned {
$($accum,)*
{
$crate::VersionQualityRange {
from: (semver::Version::parse($from).unwrap(), slang_location!()),
quality: ($crate::VersionQuality::$quality, slang_location!())
from: semver::Version::parse($from).unwrap(),
quality: $crate::VersionQuality::$quality,
}
}
]
Expand All @@ -565,7 +531,6 @@ macro_rules! slang_dsl_versioned {
$crate::$node_type::Versioned(
Box::new($dsl_macro!($($rest)+)),
vec! $accum,
slang_location!()
)
};

Expand Down
13 changes: 0 additions & 13 deletions crates/codegen/grammar/src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,6 @@ impl GrammarElement {
Self::PrecedenceParserDefinition(precedence_parser) => precedence_parser.name(),
}
}

pub fn source_location(&self) -> SourceLocation {
match self {
Self::ScannerDefinition(scanner) => scanner.source_location(),
Self::TriviaParserDefinition(trivia_parser) => trivia_parser.source_location(),
Self::ParserDefinition(parser) => parser.source_location(),
Self::PrecedenceParserDefinition(precedence_parser) => {
precedence_parser.source_location()
}
}
}
}

impl Into<GrammarElement> for ScannerDefinitionRef {
Expand Down Expand Up @@ -87,7 +76,6 @@ impl Into<GrammarElement> for PrecedenceParserDefinitionRef {

impl Visitable for GrammarElement {
fn accept_visitor<V: GrammarVisitor>(&self, visitor: &mut V) {
visitor.grammar_element_enter(self);
match self {
Self::ScannerDefinition(scanner) => scanner.accept_visitor(visitor),
Self::TriviaParserDefinition(trivia_parser) => trivia_parser.accept_visitor(visitor),
Expand All @@ -96,6 +84,5 @@ impl Visitable for GrammarElement {
precedence_parser.accept_visitor(visitor)
}
}
visitor.grammar_element_leave(self);
}
}
2 changes: 0 additions & 2 deletions crates/codegen/grammar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ mod grammar;
mod parser_definition;
mod precedence_parser_definition;
mod scanner_definition;
mod source_location;
mod version_quality;
mod visitor;

pub use grammar::*;
pub use parser_definition::*;
pub use precedence_parser_definition::*;
pub use scanner_definition::*;
pub use source_location::*;
pub use version_quality::*;
pub use visitor::*;
Loading