mirror of
https://github.com/ParkerTenBroeck/automata.git
synced 2026-06-07 05:28:45 -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 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
|
||||
}, sigma_upper};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
||||
pub struct TransitionFrom<'a> {
|
||||
pub state: State<'a>,
|
||||
pub letter: Option<Letter<'a>>,
|
||||
pub symbol: Symbol<'a>,
|
||||
dual_struct_serde! {
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||
pub struct TransitionFrom<'a> {
|
||||
#[serde(borrow)]
|
||||
pub state: State<'a>,
|
||||
#[serde(borrow)]
|
||||
pub letter: Option<Letter<'a>>,
|
||||
#[serde(borrow)]
|
||||
pub symbol: Symbol<'a>,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
||||
pub struct TransitionTo<'a> {
|
||||
pub state: State<'a>,
|
||||
pub stack: Vec<Symbol<'a>>,
|
||||
dual_struct_serde! {
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||
pub struct TransitionTo<'a> {
|
||||
#[serde(borrow)]
|
||||
pub state: State<'a>,
|
||||
#[serde(borrow)]
|
||||
pub stack: Vec<Symbol<'a>>,
|
||||
|
||||
pub transition: Span,
|
||||
pub function: Span,
|
||||
pub transition: Span,
|
||||
pub function: Span,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[allow(unused)]
|
||||
#[cfg_attr(feature = "serde", serde_with::serde_as)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
||||
pub struct Pda<'a> {
|
||||
pub initial_state: State<'a>,
|
||||
pub initial_stack: Symbol<'a>,
|
||||
pub states: HashMap<State<'a>, StateInfo>,
|
||||
pub symbols: HashMap<Symbol<'a>, SymbolInfo>,
|
||||
pub alphabet: HashMap<Letter<'a>, LetterInfo>,
|
||||
dual_struct_serde! { {#[serde_with::serde_as]}
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Pda<'a> {
|
||||
#[serde(borrow)]
|
||||
pub initial_state: State<'a>,
|
||||
#[serde(borrow)]
|
||||
pub initial_stack: Symbol<'a>,
|
||||
#[serde(borrow)]
|
||||
pub states: HashMap<State<'a>, StateInfo>,
|
||||
#[serde(borrow)]
|
||||
pub symbols: HashMap<Symbol<'a>, SymbolInfo>,
|
||||
#[serde(borrow)]
|
||||
pub alphabet: HashMap<Letter<'a>, LetterInfo>,
|
||||
|
||||
pub final_states: Option<HashMap<State<'a>, StateInfo>>,
|
||||
#[serde(borrow)]
|
||||
pub final_states: Option<HashMap<State<'a>, StateInfo>>,
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[serde_as(as = "serde_with::Seq<(_, _)>")]
|
||||
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
|
||||
|
||||
#[cfg(not(feature = "serde"))]
|
||||
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
|
||||
#[serde(borrow)]
|
||||
#[serde_as(as = "serde_with::Seq<(_, _)>")]
|
||||
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Pda<'a> {
|
||||
pub fn parse(
|
||||
pub fn compile(
|
||||
items: impl Iterator<Item = Spanned<ast::TopLevel<'a>>>,
|
||||
ctx: &mut Context<'a>,
|
||||
options: Options,
|
||||
|
|
|
|||
|
|
@ -2,57 +2,65 @@ use std::collections::HashSet;
|
|||
|
||||
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
|
||||
}};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
||||
pub struct TransitionFrom<'a> {
|
||||
pub state: State<'a>,
|
||||
pub symbol: Symbol<'a>,
|
||||
dual_struct_serde! {
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||
pub struct TransitionFrom<'a> {
|
||||
#[serde(borrow)]
|
||||
pub state: State<'a>,
|
||||
#[serde(borrow)]
|
||||
pub symbol: Symbol<'a>,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub enum Direction {
|
||||
Left,
|
||||
Right,
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
||||
pub struct TransitionTo<'a> {
|
||||
pub state: State<'a>,
|
||||
pub symbol: Symbol<'a>,
|
||||
pub direction: Direction,
|
||||
dual_struct_serde! {
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||
pub struct TransitionTo<'a> {
|
||||
#[serde(borrow)]
|
||||
pub state: State<'a>,
|
||||
#[serde(borrow)]
|
||||
pub symbol: Symbol<'a>,
|
||||
pub direction: Direction,
|
||||
|
||||
pub transition: Span,
|
||||
pub function: Span,
|
||||
pub transition: Span,
|
||||
pub function: Span,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[allow(unused)]
|
||||
#[cfg_attr(feature = "serde", serde_with::serde_as)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
||||
pub struct Tm<'a> {
|
||||
pub initial_state: State<'a>,
|
||||
pub initial_tape: Symbol<'a>,
|
||||
pub states: HashMap<State<'a>, StateInfo>,
|
||||
pub symbols: HashMap<Symbol<'a>, SymbolInfo>,
|
||||
dual_struct_serde! {{#[serde_with::serde_as]}
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Tm<'a> {
|
||||
#[serde(borrow)]
|
||||
pub initial_state: State<'a>,
|
||||
#[serde(borrow)]
|
||||
pub initial_tape: Symbol<'a>,
|
||||
#[serde(borrow)]
|
||||
pub states: HashMap<State<'a>, StateInfo>,
|
||||
#[serde(borrow)]
|
||||
pub symbols: HashMap<Symbol<'a>, SymbolInfo>,
|
||||
|
||||
pub final_states: HashMap<State<'a>, StateInfo>,
|
||||
#[serde(borrow)]
|
||||
pub final_states: HashMap<State<'a>, StateInfo>,
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[serde_as(as = "serde_with::Seq<(_, _)>")]
|
||||
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
|
||||
#[cfg(not(feature = "serde"))]
|
||||
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
|
||||
|
||||
#[serde(borrow)]
|
||||
#[serde_as(as = "serde_with::Seq<(_, _)>")]
|
||||
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Tm<'a> {
|
||||
pub fn parse(
|
||||
pub fn compile(
|
||||
items: impl Iterator<Item = Spanned<ast::TopLevel<'a>>>,
|
||||
ctx: &mut Context<'a>,
|
||||
options: Options,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
pub mod automatan;
|
||||
pub mod loader;
|
||||
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! dual_struct_serde {
|
||||
($({$(#[$serde_specific:meta])*})?
|
||||
|
|
@ -33,4 +32,83 @@ 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::{
|
||||
automatan::*,
|
||||
loader::{
|
||||
automatan::*, dual_enum_serde, dual_struct_serde, loader::{
|
||||
ast::TopLevel,
|
||||
log::{LogEntry, LogSink},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
pub mod ast;
|
||||
|
|
@ -120,13 +119,14 @@ impl<'a> Context<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "serde", serde(tag = "type"))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
|
||||
pub enum Machine<'a> {
|
||||
Fa(fa::Fa<'a>),
|
||||
Pda(pda::Pda<'a>),
|
||||
Tm(tm::Tm<'a>),
|
||||
dual_enum_serde!{
|
||||
{#[serde(tag = "type")] #[serde(rename_all = "snake_case")]}
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Machine<'a> {
|
||||
Fa(#[serde(borrow)] fa::Fa<'a>),
|
||||
Pda(#[serde(borrow)] pda::Pda<'a>),
|
||||
Tm(#[serde(borrow)] tm::Tm<'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)? {
|
||||
Type::Dfa => Machine::Fa(fa::Fa::compile(items, ctx, D)?),
|
||||
Type::Nfa => Machine::Fa(fa::Fa::compile(items, ctx, N)?),
|
||||
Type::Dpda => Machine::Pda(pda::Pda::parse(items, ctx, D)?),
|
||||
Type::Npda => Machine::Pda(pda::Pda::parse(items, ctx, N)?),
|
||||
Type::Tm => Machine::Tm(tm::Tm::parse(items, ctx, D)?),
|
||||
Type::Ntm => Machine::Tm(tm::Tm::parse(items, ctx, N)?),
|
||||
Type::Dpda => Machine::Pda(pda::Pda::compile(items, ctx, D)?),
|
||||
Type::Npda => Machine::Pda(pda::Pda::compile(items, ctx, N)?),
|
||||
Type::Tm => Machine::Tm(tm::Tm::compile(items, ctx, D)?),
|
||||
Type::Ntm => Machine::Tm(tm::Tm::compile(items, ctx, N)?),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue