mirror of
https://github.com/ParkerTenBroeck/automata.git
synced 2026-06-06 21:24:06 -04:00
serde nonsense
This commit is contained in:
parent
90d96f0738
commit
c06a0a0147
4 changed files with 176 additions and 81 deletions
|
|
@ -2,51 +2,60 @@ use std::collections::HashSet;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use crate::{delta_lower, gamma_upper, loader::{
|
use crate::{delta_lower, dual_struct_serde, gamma_upper, loader::{
|
||||||
Context, INITIAL_STACK, INITIAL_STATE, Spanned, ast::{self, Symbol as Sym}, log::LogSink
|
Context, INITIAL_STACK, INITIAL_STATE, Spanned, ast::{self, Symbol as Sym}, log::LogSink
|
||||||
}, sigma_upper};
|
}, sigma_upper};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
dual_struct_serde! {
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||||
pub struct TransitionFrom<'a> {
|
pub struct TransitionFrom<'a> {
|
||||||
|
#[serde(borrow)]
|
||||||
pub state: State<'a>,
|
pub state: State<'a>,
|
||||||
|
#[serde(borrow)]
|
||||||
pub letter: Option<Letter<'a>>,
|
pub letter: Option<Letter<'a>>,
|
||||||
|
#[serde(borrow)]
|
||||||
pub symbol: Symbol<'a>,
|
pub symbol: Symbol<'a>,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
dual_struct_serde! {
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||||
pub struct TransitionTo<'a> {
|
pub struct TransitionTo<'a> {
|
||||||
|
#[serde(borrow)]
|
||||||
pub state: State<'a>,
|
pub state: State<'a>,
|
||||||
|
#[serde(borrow)]
|
||||||
pub stack: Vec<Symbol<'a>>,
|
pub stack: Vec<Symbol<'a>>,
|
||||||
|
|
||||||
pub transition: Span,
|
pub transition: Span,
|
||||||
pub function: Span,
|
pub function: Span,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
dual_struct_serde! { {#[serde_with::serde_as]}
|
||||||
#[allow(unused)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg_attr(feature = "serde", serde_with::serde_as)]
|
pub struct Pda<'a> {
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
#[serde(borrow)]
|
||||||
pub struct Pda<'a> {
|
|
||||||
pub initial_state: State<'a>,
|
pub initial_state: State<'a>,
|
||||||
|
#[serde(borrow)]
|
||||||
pub initial_stack: Symbol<'a>,
|
pub initial_stack: Symbol<'a>,
|
||||||
|
#[serde(borrow)]
|
||||||
pub states: HashMap<State<'a>, StateInfo>,
|
pub states: HashMap<State<'a>, StateInfo>,
|
||||||
|
#[serde(borrow)]
|
||||||
pub symbols: HashMap<Symbol<'a>, SymbolInfo>,
|
pub symbols: HashMap<Symbol<'a>, SymbolInfo>,
|
||||||
|
#[serde(borrow)]
|
||||||
pub alphabet: HashMap<Letter<'a>, LetterInfo>,
|
pub alphabet: HashMap<Letter<'a>, LetterInfo>,
|
||||||
|
|
||||||
|
#[serde(borrow)]
|
||||||
pub final_states: Option<HashMap<State<'a>, StateInfo>>,
|
pub final_states: Option<HashMap<State<'a>, StateInfo>>,
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[serde(borrow)]
|
||||||
#[serde_as(as = "serde_with::Seq<(_, _)>")]
|
#[serde_as(as = "serde_with::Seq<(_, _)>")]
|
||||||
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
|
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
|
||||||
|
}
|
||||||
#[cfg(not(feature = "serde"))]
|
|
||||||
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Pda<'a> {
|
impl<'a> Pda<'a> {
|
||||||
pub fn parse(
|
pub fn compile(
|
||||||
items: impl Iterator<Item = Spanned<ast::TopLevel<'a>>>,
|
items: impl Iterator<Item = Spanned<ast::TopLevel<'a>>>,
|
||||||
ctx: &mut Context<'a>,
|
ctx: &mut Context<'a>,
|
||||||
options: Options,
|
options: Options,
|
||||||
|
|
|
||||||
|
|
@ -2,57 +2,65 @@ use std::collections::HashSet;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use crate::{delta_lower, gamma_upper, loader::{
|
use crate::{delta_lower, dual_struct_serde, gamma_upper, loader::{
|
||||||
BLANK_SYMBOL, Context, Spanned, ast::{self, Symbol as Sym}, log::LogSink
|
BLANK_SYMBOL, Context, Spanned, ast::{self, Symbol as Sym}, log::LogSink
|
||||||
}};
|
}};
|
||||||
|
dual_struct_serde! {
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
pub struct TransitionFrom<'a> {
|
||||||
pub struct TransitionFrom<'a> {
|
#[serde(borrow)]
|
||||||
pub state: State<'a>,
|
pub state: State<'a>,
|
||||||
|
#[serde(borrow)]
|
||||||
pub symbol: Symbol<'a>,
|
pub symbol: Symbol<'a>,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
pub enum Direction {
|
pub enum Direction {
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
dual_struct_serde! {
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||||
pub struct TransitionTo<'a> {
|
pub struct TransitionTo<'a> {
|
||||||
|
#[serde(borrow)]
|
||||||
pub state: State<'a>,
|
pub state: State<'a>,
|
||||||
|
#[serde(borrow)]
|
||||||
pub symbol: Symbol<'a>,
|
pub symbol: Symbol<'a>,
|
||||||
pub direction: Direction,
|
pub direction: Direction,
|
||||||
|
|
||||||
pub transition: Span,
|
pub transition: Span,
|
||||||
pub function: Span,
|
pub function: Span,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
dual_struct_serde! {{#[serde_with::serde_as]}
|
||||||
#[allow(unused)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg_attr(feature = "serde", serde_with::serde_as)]
|
pub struct Tm<'a> {
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
#[serde(borrow)]
|
||||||
pub struct Tm<'a> {
|
|
||||||
pub initial_state: State<'a>,
|
pub initial_state: State<'a>,
|
||||||
|
#[serde(borrow)]
|
||||||
pub initial_tape: Symbol<'a>,
|
pub initial_tape: Symbol<'a>,
|
||||||
|
#[serde(borrow)]
|
||||||
pub states: HashMap<State<'a>, StateInfo>,
|
pub states: HashMap<State<'a>, StateInfo>,
|
||||||
|
#[serde(borrow)]
|
||||||
pub symbols: HashMap<Symbol<'a>, SymbolInfo>,
|
pub symbols: HashMap<Symbol<'a>, SymbolInfo>,
|
||||||
|
|
||||||
|
#[serde(borrow)]
|
||||||
pub final_states: HashMap<State<'a>, StateInfo>,
|
pub final_states: HashMap<State<'a>, StateInfo>,
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
|
#[serde(borrow)]
|
||||||
#[serde_as(as = "serde_with::Seq<(_, _)>")]
|
#[serde_as(as = "serde_with::Seq<(_, _)>")]
|
||||||
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
|
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
|
||||||
#[cfg(not(feature = "serde"))]
|
}
|
||||||
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Tm<'a> {
|
impl<'a> Tm<'a> {
|
||||||
pub fn parse(
|
pub fn compile(
|
||||||
items: impl Iterator<Item = Spanned<ast::TopLevel<'a>>>,
|
items: impl Iterator<Item = Spanned<ast::TopLevel<'a>>>,
|
||||||
ctx: &mut Context<'a>,
|
ctx: &mut Context<'a>,
|
||||||
options: Options,
|
options: Options,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
pub mod automatan;
|
pub mod automatan;
|
||||||
pub mod loader;
|
pub mod loader;
|
||||||
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! dual_struct_serde {
|
macro_rules! dual_struct_serde {
|
||||||
($({$(#[$serde_specific:meta])*})?
|
($({$(#[$serde_specific:meta])*})?
|
||||||
|
|
@ -34,3 +33,82 @@ macro_rules! dual_struct_serde {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! dual_enum_serde {
|
||||||
|
(
|
||||||
|
$( {$(#[$serde_specific:meta])*} )?
|
||||||
|
$(#[$enum_meta:meta])*
|
||||||
|
$vis:vis enum $Name:ident $(<$($gen:tt),*>)?
|
||||||
|
{
|
||||||
|
$(
|
||||||
|
$(#[$variant_meta:meta])*
|
||||||
|
$Variant:ident
|
||||||
|
$(
|
||||||
|
// Tuple variant: Variant(T1, T2, ...)
|
||||||
|
( $(
|
||||||
|
$(#[$tfield_meta:meta])*
|
||||||
|
$tfield_ty:ty
|
||||||
|
),* $(,)? )
|
||||||
|
)?
|
||||||
|
$(
|
||||||
|
// Struct variant: Variant { a: T, b: U, ... }
|
||||||
|
{ $(
|
||||||
|
$(#[$sfield_meta:meta])*
|
||||||
|
$sfield_vis:vis $sfield_name:ident : $sfield_ty:ty
|
||||||
|
),* $(,)? }
|
||||||
|
)?
|
||||||
|
),* $(,)?
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
$(#[$enum_meta])*
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
$( $(#[$serde_specific])* )?
|
||||||
|
$vis enum $Name $(<$($gen),*>)? {
|
||||||
|
$(
|
||||||
|
$(#[$variant_meta])*
|
||||||
|
$Variant
|
||||||
|
$(
|
||||||
|
(
|
||||||
|
$(
|
||||||
|
$(#[$tfield_meta])*
|
||||||
|
$tfield_ty
|
||||||
|
),*
|
||||||
|
)
|
||||||
|
)?
|
||||||
|
$(
|
||||||
|
{
|
||||||
|
$(
|
||||||
|
$(#[$sfield_meta])*
|
||||||
|
$sfield_vis $sfield_name: $sfield_ty
|
||||||
|
),*
|
||||||
|
}
|
||||||
|
)?
|
||||||
|
),*
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "serde"))]
|
||||||
|
$(#[$enum_meta])*
|
||||||
|
$vis enum $Name $(<$($gen),*>)? {
|
||||||
|
$(
|
||||||
|
// strip variant + field attrs in non-serde version
|
||||||
|
$Variant
|
||||||
|
$(
|
||||||
|
(
|
||||||
|
$(
|
||||||
|
$tfield_ty
|
||||||
|
),*
|
||||||
|
)
|
||||||
|
)?
|
||||||
|
$(
|
||||||
|
{
|
||||||
|
$(
|
||||||
|
$sfield_vis $sfield_name: $sfield_ty
|
||||||
|
),*
|
||||||
|
}
|
||||||
|
)?
|
||||||
|
),*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
automatan::*,
|
automatan::*, dual_enum_serde, dual_struct_serde, loader::{
|
||||||
loader::{
|
|
||||||
ast::TopLevel,
|
ast::TopLevel,
|
||||||
log::{LogEntry, LogSink},
|
log::{LogEntry, LogSink},
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod ast;
|
pub mod ast;
|
||||||
|
|
@ -120,13 +119,14 @@ impl<'a> Context<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
dual_enum_serde!{
|
||||||
#[cfg_attr(feature = "serde", serde(tag = "type"))]
|
{#[serde(tag = "type")] #[serde(rename_all = "snake_case")]}
|
||||||
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Machine<'a> {
|
pub enum Machine<'a> {
|
||||||
Fa(fa::Fa<'a>),
|
Fa(#[serde(borrow)] fa::Fa<'a>),
|
||||||
Pda(pda::Pda<'a>),
|
Pda(#[serde(borrow)] pda::Pda<'a>),
|
||||||
Tm(tm::Tm<'a>),
|
Tm(#[serde(borrow)] tm::Tm<'a>),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_universal<'a>(ctx: &mut Context<'a>) -> Option<Machine<'a>> {
|
pub fn parse_universal<'a>(ctx: &mut Context<'a>) -> Option<Machine<'a>> {
|
||||||
|
|
@ -194,9 +194,9 @@ pub fn parse_universal<'a>(ctx: &mut Context<'a>) -> Option<Machine<'a>> {
|
||||||
Some(match parse_type(items.next(), ctx)? {
|
Some(match parse_type(items.next(), ctx)? {
|
||||||
Type::Dfa => Machine::Fa(fa::Fa::compile(items, ctx, D)?),
|
Type::Dfa => Machine::Fa(fa::Fa::compile(items, ctx, D)?),
|
||||||
Type::Nfa => Machine::Fa(fa::Fa::compile(items, ctx, N)?),
|
Type::Nfa => Machine::Fa(fa::Fa::compile(items, ctx, N)?),
|
||||||
Type::Dpda => Machine::Pda(pda::Pda::parse(items, ctx, D)?),
|
Type::Dpda => Machine::Pda(pda::Pda::compile(items, ctx, D)?),
|
||||||
Type::Npda => Machine::Pda(pda::Pda::parse(items, ctx, N)?),
|
Type::Npda => Machine::Pda(pda::Pda::compile(items, ctx, N)?),
|
||||||
Type::Tm => Machine::Tm(tm::Tm::parse(items, ctx, D)?),
|
Type::Tm => Machine::Tm(tm::Tm::compile(items, ctx, D)?),
|
||||||
Type::Ntm => Machine::Tm(tm::Tm::parse(items, ctx, N)?),
|
Type::Ntm => Machine::Tm(tm::Tm::compile(items, ctx, N)?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue