Skip to content

Commit

Permalink
Refactor grammar
Browse files Browse the repository at this point in the history
  • Loading branch information
0x2a-42 committed Dec 27, 2024
1 parent 95fbf0d commit 2564f2a
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 137 deletions.
44 changes: 10 additions & 34 deletions src/frontend/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,6 @@ macro_rules! ast_node {
}
}
};
($node_name:ident, $rule_name:ident, $token_name:ident) => {
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, Ord, PartialOrd)]
pub struct $node_name {
syntax: NodeRef,
}
impl AstNode for $node_name {
fn cast(cst: &Cst, syntax: NodeRef) -> Option<Self> {
match cst.get(syntax) {
Node::Rule(Rule::$rule_name, _)
if cst
.children(syntax)
.find_map(|n| cst.get_token(n, Token::$token_name))
.is_some() =>
{
Some(Self { syntax })
}
_ => None,
}
}
fn syntax(&self) -> NodeRef {
self.syntax
}
}
};
($node_name:ident, ($($node_names:ident),+)) => {
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, Ord, PartialOrd)]
pub enum $node_name {
Expand Down Expand Up @@ -106,16 +82,16 @@ ast_node!(Alternation);
ast_node!(Concat);
ast_node!(Paren);
ast_node!(Optional);
ast_node!(Star, Postfix, Star);
ast_node!(Plus, Postfix, Plus);
ast_node!(Name, Atomic, Id);
ast_node!(Symbol, Atomic, Str);
ast_node!(Predicate, Atomic, Predicate);
ast_node!(Action, Atomic, Action);
ast_node!(NodeRename, Atomic, NodeRename);
ast_node!(NodeElision, Atomic, Hat);
ast_node!(NodeMarker, Atomic, NodeMarker);
ast_node!(NodeCreation, Atomic, NodeCreation);
ast_node!(Star);
ast_node!(Plus);
ast_node!(Name);
ast_node!(Symbol);
ast_node!(Predicate);
ast_node!(Action);
ast_node!(NodeRename);
ast_node!(NodeElision);
ast_node!(NodeMarker);
ast_node!(NodeCreation);

impl Cst<'_> {
fn child_node<T: AstNode>(&self, syntax: NodeRef) -> Option<T> {
Expand Down
172 changes: 85 additions & 87 deletions src/frontend/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,18 @@ pub enum Rule {
Alternation,
Concat,
Postfix,
Paren,
Action,
Name,
NodeCreation,
NodeElision,
NodeMarker,
NodeRename,
Optional,
Atomic,
Paren,
Plus,
Predicate,
Star,
Symbol,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
Expand Down Expand Up @@ -746,24 +755,74 @@ impl<'a> Parser<'a> {
}
}
}
#[allow(unused_assignments)]
fn r#postfix(&mut self, diags: &mut Vec<Diagnostic>) {
fn rec(parser: &mut Parser, diags: &mut Vec<Diagnostic>, mut lhs: MarkClosed) {
let mut node_kind = Rule::Postfix;
match parser.current {
Token::Action
| Token::Hat
| Token::Id
| Token::NodeCreation
| Token::NodeMarker
| Token::NodeRename
| Token::Predicate
| Token::Str => {
parser.r#atomic(diags);
}
Token::LPar => {
parser.r#paren(diags);
let m = parser.cst.open();
expect!(LPar, "(", parser, diags);
parser.r#regex(diags);
expect!(RPar, ")", parser, diags);
node_kind = Rule::Paren;
parser.close(m, node_kind, diags);
}
Token::LBrak => {
parser.r#optional(diags);
let m = parser.cst.open();
expect!(LBrak, "[", parser, diags);
parser.r#regex(diags);
expect!(RBrak, "]", parser, diags);
node_kind = Rule::Optional;
parser.close(m, node_kind, diags);
}
Token::Id => {
let m = parser.cst.open();
expect!(Id, "<identifier>", parser, diags);
node_kind = Rule::Name;
parser.close(m, node_kind, diags);
}
Token::Str => {
let m = parser.cst.open();
expect!(Str, "<string literal>", parser, diags);
node_kind = Rule::Symbol;
parser.close(m, node_kind, diags);
}
Token::Predicate => {
let m = parser.cst.open();
expect!(Predicate, "<semantic predicate>", parser, diags);
node_kind = Rule::Predicate;
parser.close(m, node_kind, diags);
}
Token::Action => {
let m = parser.cst.open();
expect!(Action, "<semantic action>", parser, diags);
node_kind = Rule::Action;
parser.close(m, node_kind, diags);
}
Token::NodeRename => {
let m = parser.cst.open();
expect!(NodeRename, "<node rename>", parser, diags);
node_kind = Rule::NodeRename;
parser.close(m, node_kind, diags);
}
Token::NodeMarker => {
let m = parser.cst.open();
expect!(NodeMarker, "<node marker>", parser, diags);
node_kind = Rule::NodeMarker;
parser.close(m, node_kind, diags);
}
Token::NodeCreation => {
let m = parser.cst.open();
expect!(NodeCreation, "<node creation>", parser, diags);
node_kind = Rule::NodeCreation;
parser.close(m, node_kind, diags);
}
Token::Hat => {
let m = parser.cst.open();
expect!(Hat, "^", parser, diags);
node_kind = Rule::NodeElision;
parser.close(m, node_kind, diags);
}
_ => {
parser.error(
Expand All @@ -785,21 +844,20 @@ impl<'a> Parser<'a> {
}
}
loop {
node_kind = Rule::Postfix;
match parser.current {
Token::Plus | Token::Star => {
Token::Star => {
let m = parser.cst.open_before(lhs);
match parser.current {
Token::Star => {
expect!(Star, "*", parser, diags);
}
Token::Plus => {
expect!(Plus, "+", parser, diags);
}
_ => {
parser.error(diags, err![parser.span(), "+", "*"]);
}
}
lhs = parser.close(m, Rule::Postfix, diags);
expect!(Star, "*", parser, diags);
node_kind = Rule::Star;
lhs = parser.close(m, node_kind, diags);
continue;
}
Token::Plus => {
let m = parser.cst.open_before(lhs);
expect!(Plus, "+", parser, diags);
node_kind = Rule::Plus;
lhs = parser.close(m, node_kind, diags);
continue;
}
_ => {
Expand All @@ -811,66 +869,6 @@ impl<'a> Parser<'a> {
let lhs = self.cst.mark();
rec(self, diags, lhs);
}
fn r#paren(&mut self, diags: &mut Vec<Diagnostic>) {
let m = self.cst.open();
expect!(LPar, "(", self, diags);
self.r#regex(diags);
expect!(RPar, ")", self, diags);
self.close(m, Rule::Paren, diags);
}
fn r#optional(&mut self, diags: &mut Vec<Diagnostic>) {
let m = self.cst.open();
expect!(LBrak, "[", self, diags);
self.r#regex(diags);
expect!(RBrak, "]", self, diags);
self.close(m, Rule::Optional, diags);
}
fn r#atomic(&mut self, diags: &mut Vec<Diagnostic>) {
let m = self.cst.open();
match self.current {
Token::Id => {
expect!(Id, "<identifier>", self, diags);
}
Token::Str => {
expect!(Str, "<string literal>", self, diags);
}
Token::Predicate => {
expect!(Predicate, "<semantic predicate>", self, diags);
}
Token::Action => {
expect!(Action, "<semantic action>", self, diags);
}
Token::NodeRename => {
expect!(NodeRename, "<node rename>", self, diags);
}
Token::NodeMarker => {
expect!(NodeMarker, "<node marker>", self, diags);
}
Token::NodeCreation => {
expect!(NodeCreation, "<node creation>", self, diags);
}
Token::Hat => {
expect!(Hat, "^", self, diags);
}
_ => {
self.error(
diags,
err![
self.span(),
"<semantic action>",
"^",
"<identifier>",
"<node creation>",
"<node marker>",
"<node rename>",
"<semantic predicate>",
"<string literal>"
],
);
}
}
self.close(m, Rule::Atomic, diags);
}
}

trait PredicatesAndActions {
Expand Down
28 changes: 12 additions & 16 deletions src/frontend/lelwel.llw
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,16 @@ regex^: alternation;
alternation^: concat [('|' concat)+ >];
concat^: postfix [postfix+ >];
postfix:
postfix ('*' | '+')
| atomic ^
| paren ^
| optional ^
;
paren: '(' regex ')';
optional: '[' regex ']';
atomic:
Id
| Str
| Predicate
| Action
| NodeRename
| NodeMarker
| NodeCreation
| '^'
postfix '*' @star
| postfix '+' @plus
| '(' regex ')' @paren
| '[' regex ']' @optional
| Id @name
| Str @symbol
| Predicate @predicate
| Action @action
| NodeRename @node_rename
| NodeMarker @node_marker
| NodeCreation @node_creation
| '^' @node_elision
;

0 comments on commit 2564f2a

Please sign in to comment.