use std::fmt::Display;
use pest::iterators::Pair;
use crate::{ccarp::error::{rule_err, rule_mismatch, safe_remove, safe_unwrap, CCErr, Result}, ccarp_rust::defs::sum};
use super::{defs::{list_ast, Rule, AST}, expr::{AssignmentExpr, ConstExpr}, tt::Identifier};
pub type NonEmptyVec<T>=Vec<T>;
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Declaration(pub DeclarationSpecifiers, pub Option<InitDeclaratorList>); impl AST for Declaration {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::decl => {
let mut inner=pair.into_inner();
let specs=DeclarationSpecifiers::take(safe_unwrap!(inner.next(),"Declaration"))?;
if let Some(pair)=inner.next() { Ok(Self(specs, Some(InitDeclaratorList::take(pair)?))) }
else { Ok(Self(specs, None)) }
},
_ => Err(rule_mismatch!(pair))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct DeclarationSpecifiers(pub NonEmptyVec<Specifier>); impl AST for DeclarationSpecifiers {
fn take(pair: Pair<Rule>) -> Result<Self> {
let mut v=vec![];
match pair.as_rule() {
Rule::specs => {
for pair in pair.into_inner() { v.push(Specifier::take(pair)?); } Ok(Self(v))
},
_ => Err(rule_mismatch!(pair,specs))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Specifier {
Storage(StorageSpecifier), Type(TypeSpecifier), Typedef(TypedefName), TypeQ(TypeQualifier), Func(FuncSpecifier) }
impl AST for Specifier {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::storage_spec => Ok(Self::Storage(StorageSpecifier::take(pair)?)), Rule::type_qual => Ok(Self::TypeQ(TypeQualifier::take(pair)?)), Rule::func_spec => Ok(Self::Func(FuncSpecifier::take(pair)?)), Rule::type_spec => Ok(Self::Type(TypeSpecifier::take(pair)?)), Rule::typedef_name => Ok(Self::Typedef(TypedefName::take(pair)?)), _ => Err(rule_mismatch!(pair))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum StorageSpecifier {
Typedef,
Extern,
Static,
Auto,
Register
}
impl AST for StorageSpecifier {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_str() {
"typedef" => Ok(Self::Typedef),
"extern" => Ok(Self::Extern),
"static" => Ok(Self::Static),
"auto" => Ok(Self::Auto),
"register" => Ok(Self::Register),
_ => Err(rule_mismatch!(pair))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum TypeSpecifier {
Void,
Char,
Short,
Int,
Long,
Float,
Double,
Signed,
Unsigned,
Bool,
Complex,
Imaginary,
Struct(Box<StructSpecifier>),
Enum(Box<EnumSpecifier>),
}
impl AST for TypeSpecifier {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::type_spec => {
match pair.as_str() {
"void" => Ok(Self::Void),
"char" => Ok(Self::Char),
"short" => Ok(Self::Short),
"int" => Ok(Self::Int),
"long" => Ok(Self::Long),
"float" => Ok(Self::Float),
"double" => Ok(Self::Double),
"signed" => Ok(Self::Signed),
"unsigned" => Ok(Self::Unsigned),
"_Bool" => Ok(Self::Bool),
"_Complex" => Ok(Self::Complex),
"_Imaginary" => Ok(Self::Imaginary),
_ => {
let pair=safe_unwrap!(pair.into_inner().next(),"Type Specifier");
match pair.as_rule() {
Rule::struct_spec => Ok(Self::Struct(Box::new(StructSpecifier::take(pair)?))),
Rule::enum_spec => Ok(Self::Enum(Box::new(EnumSpecifier::take(pair)?))),
_ => Err(rule_mismatch!(pair))
}
}
}
}
_ => Err(rule_mismatch!(pair,type_spec))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct TypedefName(pub Identifier);
impl AST for TypedefName {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::typedef_name => {
let pair=safe_unwrap!(pair.into_inner().next(),"Typedef Name");
match pair.as_rule() {
Rule::tok_ident => Ok(Self(Identifier::take(pair)?)), _ => Err(rule_mismatch!(pair,tok_ident))
}
},
_ => Err(rule_mismatch!(pair,typedef_name))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum TypeQualifier {
Const,
Restrict,
Volatile
}
impl AST for TypeQualifier {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_str() {
"const" => Ok(Self::Const),
"restrict" => Ok(Self::Restrict),
"volatile" => Ok(Self::Volatile),
_ => Err(rule_mismatch!(pair))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum FuncSpecifier {
Inline
}
impl AST for FuncSpecifier {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_str() {
"inline" => Ok(Self::Inline),
_ => Err(rule_mismatch!(pair))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct InitDeclaratorList(pub NonEmptyVec<InitDeclarator>); list_ast!(InitDeclaratorList : InitDeclarator where init_decl_list => init_decl);
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum InitDeclarator {
Decl(Box<Declarator>), Assign(Box<Declarator>,Initialiser) }
impl AST for InitDeclarator {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::init_decl => {
let mut inner=pair.into_inner();
let decl=Declarator::take(safe_unwrap!(inner.next(),"Init Declarator"))?; if let Some(pair)=inner.next() { Ok(Self::Assign(Box::new(decl),Initialiser::take(pair)?)) } else { Ok(Self::Decl(Box::new(decl))) } },
_ => Err(rule_mismatch!(pair,init_decl))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Declarator(pub Option<Pointer>,pub Box<DirectDeclarator>); impl AST for Declarator {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::declarator => {
let mut inner=pair.into_inner();
let pair=safe_unwrap!(inner.next(),"Declarator");
match pair.as_rule() {
Rule::direct_declarator => Ok(Self(None,Box::new(DirectDeclarator::take(pair)?))), Rule::pointer => Ok(Self(Some(Pointer::take(pair)?),Box::new(DirectDeclarator::take(safe_unwrap!(inner.next(),"Declarator"))?))), _ => Err(rule_mismatch!(pair))
}
},
_ => Err(rule_mismatch!(pair,declarator))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum DirectDeclarator {
Ident(Identifier,Vec<DeclPostfix>), Decl(Box<Declarator>,Vec<DeclPostfix>), }
impl AST for DirectDeclarator {
fn take(pair: Pair<Rule>) -> Result<Self> {
sum!(IdentOrDecl;Identifier;Declarator);
match pair.as_rule() {
Rule::direct_declarator => {
let mut v=vec![];
let mut inner=pair.into_inner();
let pair=safe_unwrap!(inner.next(),"Direct Declarator");
let ident_or_decl=
match pair.as_rule() {
Rule::tok_ident => IdentOrDecl::A(Identifier::take(pair)?), Rule::decl => IdentOrDecl::B(Declarator::take(pair)?), _ => return Err(rule_mismatch!(pair))
};
for pair in inner { v.push(DeclPostfix::take(pair)?) } match ident_or_decl {
IdentOrDecl::A(identifier) => Ok(Self::Ident(identifier, v)), IdentOrDecl::B(declarator) => Ok(Self::Decl(Box::new(declarator), v)), }
},
_ => Err(rule_mismatch!(pair,direct_declarator))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum DeclPostfix {
Opt(Option<TypeQualifierList>,Option<Box<AssignmentExpr>>), Static(Option<TypeQualifierList>,Box<AssignmentExpr>), Point(Option<TypeQualifierList>), Param(ParameterTypeList), IdentList(Option<IdentifierList>), }
impl AST for DeclPostfix {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::decl_postfix => {
let mut qual=None; let mut bracket=false; let mut mul=false; let mut stat=false; for pair in pair.into_inner() {
match pair.as_rule() {
Rule::type_qual => qual=Some(TypeQualifierList::take(pair)?), Rule::assign_expr => {
if stat { return Ok(Self::Static(qual, Box::new(AssignmentExpr::take(pair)?))) } return Ok(Self::Opt(qual, Some(Box::new(AssignmentExpr::take(pair)?)))) },
Rule::param_type_list => return Ok(Self::Param(ParameterTypeList::take(pair)?)), Rule::ident_list => return Ok(Self::IdentList(Some(IdentifierList::take(pair)?))), Rule::op_br|Rule::cl_br => bracket=true, Rule::mul => mul=true, Rule::stat => stat=true, _ => return Err(rule_mismatch!(pair))
}
}
if mul { Ok(Self::Point(qual)) } else if bracket { Ok(Self::Opt(qual, None)) } else { Ok(Self::IdentList(None)) } },
_ => Err(rule_mismatch!(pair,decl_postfix))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Pointer(pub NonEmptyVec<Option<TypeQualifierList>>); impl AST for Pointer {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::pointer => {
let mut v=vec![];
let mut elem=None; for pair in pair.into_inner() {
match pair.as_rule() {
Rule::type_qual_list => elem=Some(TypeQualifierList::take(pair)?), Rule::mul => { v.push(elem); elem=None }, _ => return Err(rule_mismatch!(pair))
}
}
safe_remove(&mut v, 0, rule_mismatch!("Pointer",Some))?; v.push(elem); Ok(Self(v))
},
_ => Err(rule_mismatch!(pair,pointer))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct TypeQualifierList(pub NonEmptyVec<TypeQualifier>); list_ast!(TypeQualifierList : TypeQualifier where type_qual_list => type_qual);
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum ParameterTypeList {
List(ParameterList), TripleDot(ParameterList) }
impl AST for ParameterTypeList {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::param_type_list => {
let mut inner=pair.into_inner();
let params=ParameterList::take(safe_unwrap!(inner.next(),"Parameter Type List"))?; if inner.next().is_some() { Ok(Self::TripleDot(params)) } else { Ok(Self::List(params)) } },
_ => Err(rule_mismatch!(pair,param_type_list))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ParameterList(pub NonEmptyVec<ParameterDeclaration>); list_ast!(ParameterList : ParameterDeclaration where param_list => param_decl);
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum ParameterDeclaration {
Decl(DeclarationSpecifiers,Box<Declarator>), Abstract(DeclarationSpecifiers,Option<Box<AbstractDeclarator>>) }
impl AST for ParameterDeclaration {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::param_decl => {
let mut inner=pair.into_inner();
let spec=DeclarationSpecifiers::take(safe_unwrap!(inner.next(),"Parameter Declaration"))?; if let Some(pair)=inner.next() {
match pair.as_rule() {
Rule::declarator => Ok(Self::Decl(spec,Box::new(Declarator::take(pair)?))), Rule::abstract_declarator => Ok(Self::Abstract(spec,Some(Box::new(AbstractDeclarator::take(pair)?)))), _ => Err(rule_mismatch!(pair))
}
}
else { Ok(Self::Abstract(spec,None)) } },
_ => Err(rule_mismatch!(pair,param_decl))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct IdentifierList(pub NonEmptyVec<Identifier>); list_ast!(IdentifierList : Identifier where ident_list => tok_ident);
impl From<ParameterTypeList> for IdentifierList {
fn from(value: ParameterTypeList) -> Self {
let list=
match value {
ParameterTypeList::List(parameter_list)|ParameterTypeList::TripleDot(parameter_list) => parameter_list,
};
let mut v=vec![];
for decl in list.0 {
if let ParameterDeclaration::Abstract(DeclarationSpecifiers(specs), None)=decl {
if let [Specifier::Typedef(TypedefName(ident))]=&specs[..] {
v.push(ident.clone());
}
}
}
Self(v)
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct TypeName(pub SpecifierQualifierList,pub Option<Box<AbstractDeclarator>>); impl AST for TypeName {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::type_name => {
let mut inner=pair.into_inner();
let list=SpecifierQualifierList::take(safe_unwrap!(inner.next(),"Type Name"))?; if let Some(pair)=inner.next() { Ok(Self(list, Some(Box::new(AbstractDeclarator::take(pair)?)))) } else { Ok(Self(list,None)) } },
_ => Err(rule_mismatch!(pair,type_name))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum AbstractDeclarator {
Pointer(Pointer), Direct(Option<Pointer>,Box<DirectAbstractDeclarator>) }
impl AST for AbstractDeclarator {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::abstract_declarator => {
let mut inner=pair.into_inner();
let pair=safe_unwrap!(inner.next(),"Abstract Declarator");
match pair.as_rule() {
Rule::direct_abstract_declarator => Ok(Self::Direct(None,Box::new(DirectAbstractDeclarator::take(pair)?))), Rule::pointer => {
let point=Pointer::take(pair)?;
if let Some(pair)=inner.next() { Ok(Self::Direct(Some(point),Box::new(DirectAbstractDeclarator::take(pair)?))) } else { Ok(Self::Pointer(point)) } },
_ => Err(rule_mismatch!(pair))
}
},
_ => Err(rule_mismatch!(pair,abstract_declarator))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum DirectAbstractDeclarator {
Abstract(Box<AbstractDeclarator>), Post(Option<Box<AbstractDeclarator>>,NonEmptyVec<DirectAbstractDeclaratorPostfix>), }
impl AST for DirectAbstractDeclarator {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::direct_abstract_declarator => {
let mut decl=None; let mut v=vec![];
for pair in pair.into_inner() {
match pair.as_rule() {
Rule::abstract_declarator => decl=Some(AbstractDeclarator::take(pair)?), Rule::direct_abstract_declarator_postfix => v.push(DirectAbstractDeclaratorPostfix::take(pair)?), _ => return Err(rule_mismatch!(pair))
}
}
if v.is_empty() { Ok(Self::Abstract(Box::new(safe_unwrap!(decl,"Direct Abstract Declarator")))) } else { Ok(Self::Post(decl.map(Box::new), v)) } },
_ => Err(rule_mismatch!(pair,direct_abstract_declarator))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum DirectAbstractDeclaratorPostfix {
Parent(Option<ParameterTypeList>), Assign(Option<AssignmentExpr>), Pointer }
impl AST for DirectAbstractDeclaratorPostfix {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::direct_abstract_declarator_postfix => {
let mut inner=pair.into_inner();
let pair=inner.next();
pair.map_or(Ok(Self::Parent(None)) , |pair| match pair.as_rule() {
Rule::param_type_list => Ok(Self::Parent(Some(ParameterTypeList::take(pair)?))), Rule::op_br => {
let pair=inner.next();
pair.map_or(Ok(Self::Assign(None)) , |pair| match pair.as_rule() {
Rule::assign_expr => Ok(Self::Assign(Some(AssignmentExpr::take(pair)?))), Rule::mul => Ok(Self::Pointer), _ => Err(rule_mismatch!(pair))
})
},
_ => Err(rule_mismatch!(pair))
})
},
_ => Err(rule_mismatch!(pair,direct_abstract_declarator_postfix))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Initialiser {
Assign(AssignmentExpr), Init(Box<InitialiserList>) }
impl AST for Initialiser {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::init => {
let pair=safe_unwrap!(pair.into_inner().next(),"Initialiser");
match pair.as_rule() {
Rule::assign_expr => Ok(Self::Assign(AssignmentExpr::take(pair)?)), Rule::init_list => Ok(Self::Init(Box::new(InitialiserList::take(pair)?))), _ => Err(rule_mismatch!(pair))
}
},
_ => Err(rule_mismatch!(pair,init))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct InitialiserList(pub NonEmptyVec<(Option<Designation>,Initialiser)>); impl AST for InitialiserList {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::init_list => {
let mut v=vec![];
let mut des=None; for pair in pair.into_inner() {
match pair.as_rule() {
Rule::designation => des=Some(Designation::take(pair)?), Rule::init => { v.push((des,Initialiser::take(pair)?)); des=None }, _ => return Err(rule_mismatch!(pair))
}
}
Ok(Self(v))
},
_ => Err(rule_mismatch!(pair,init_list))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Designation(pub DesignatorList); impl AST for Designation {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::designation => {
let pair=safe_unwrap!(pair.into_inner().next(),"Designator");
match pair.as_rule() {
Rule::designator_list => Ok(Self(DesignatorList::take(pair)?)), _ => Err(rule_mismatch!(pair))
}
},
_ => Err(rule_mismatch!(pair,designator))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct DesignatorList(pub NonEmptyVec<Designator>); list_ast!(DesignatorList : Designator where designator_list => designator);
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Designator {
Const(ConstExpr), Ident(Identifier) }
impl AST for Designator {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::designator => {
let mut inner=pair.into_inner();
let pair=safe_unwrap!(inner.next(),"Designator");
match pair.as_rule() {
Rule::tok_ident => Ok(Self::Ident(Identifier::take(pair)?)), Rule::const_expr => Ok(Self::Const(ConstExpr::take(pair)?)), _ => Err(rule_mismatch!(pair))
}
},
_ => Err(rule_mismatch!(pair,designator))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum StructSpecifier {
Full(StructOrUnion,Option<Identifier>,Box<StructDeclarationList>), Decl(StructOrUnion,Identifier) }
impl AST for StructSpecifier {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::struct_spec => {
let mut inner=pair.into_inner();
let str_uni=StructOrUnion::take(safe_unwrap!(inner.next(),"Struct Specifier"))?;
let pair=safe_unwrap!(inner.next(),"Struct Specifier");
match pair.as_rule() {
Rule::struct_declaration_list => Ok(Self::Full(str_uni, None, Box::new(StructDeclarationList::take(pair)?))),
Rule::tok_ident => {
let ident=Identifier::take(pair)?;
if let Some(pair)=inner.next() { Ok(Self::Full(str_uni, Some(ident), Box::new(StructDeclarationList::take(pair)?))) }
else { Ok(Self::Decl(str_uni, ident)) }
},
_ => Err(rule_mismatch!(pair))
}
},
_ => Err(rule_mismatch!(pair,struct_spec))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum StructOrUnion {
Struct,
Union
}
impl AST for StructOrUnion {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_str() {
"struct" => Ok(Self::Struct),
"union" => Ok(Self::Union),
_ => Err(rule_mismatch!(pair))
}
}
}
impl Display for StructOrUnion {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Struct => write!(f,"struct"),
Self::Union => write!(f,"union"),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct StructDeclarationList(pub NonEmptyVec<StructDeclaration>); list_ast!(StructDeclarationList : StructDeclaration where struct_declaration_list => struct_declaration);
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct StructDeclaration(pub Box<SpecifierQualifierList>,pub StructDeclaratorList); impl AST for StructDeclaration {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::struct_declaration => {
let mut inner=pair.into_inner();
let list=SpecifierQualifierList::take(safe_unwrap!(inner.next(),"Struct Declaration"))?; Ok(Self(Box::new(list),StructDeclaratorList::take(safe_unwrap!(inner.next(),"Struct Declaration"))?)) },
_ => Err(rule_mismatch!(pair,struct_declaration))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct SpecifierQualifierList(pub Vec<SpecifierQualifier>); impl AST for SpecifierQualifierList {
fn take(pair: Pair<Rule>) -> Result<Self> {
let mut v=vec![];
match pair.as_rule() {
Rule::spec_qual_list => {
for pair in pair.into_inner() { v.push(SpecifierQualifier::take(pair)?); } Ok(Self(v)) },
_ => Err(rule_mismatch!(pair,spec_qual_list))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum SpecifierQualifier {
Spec(TypeSpecifier), Typedef(TypedefName), Qualif(TypeQualifier) }
impl AST for SpecifierQualifier {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::type_qual => Ok(Self::Qualif(TypeQualifier::take(pair)?)), Rule::type_spec => Ok(Self::Spec(TypeSpecifier::take(pair)?)), Rule::typedef_name => Ok(Self::Typedef(TypedefName::take(pair)?)), _ => Err(rule_mismatch!(pair))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct StructDeclaratorList(pub NonEmptyVec<StructDeclarator>); list_ast!(StructDeclaratorList : StructDeclarator where struct_declarator_list => struct_declarator);
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum StructDeclarator {
Decl(Box<Declarator>), Const(Option<Box<Declarator>>,Box<ConstExpr>) }
impl AST for StructDeclarator {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::struct_declarator => {
let mut inner=pair.into_inner();
let pair=safe_unwrap!(inner.next(),"Struct Declarator");
match pair.as_rule() {
Rule::declarator => {
let decl=Declarator::take(pair)?;
if let Some(pair)=inner.next() { Ok(Self::Const(Some(Box::new(decl)), Box::new(ConstExpr::take(pair)?))) } else { Ok(Self::Decl(Box::new(decl))) } },
Rule::const_expr => Ok(Self::Const(None, Box::new(ConstExpr::take(pair)?))), _ => Err(rule_mismatch!(pair))
}
},
_ => Err(rule_mismatch!(pair,struct_declarator))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum EnumSpecifier {
Full(Option<Identifier>,Box<EnumeratorList>), Decl(Identifier) }
impl AST for EnumSpecifier {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::enum_spec => {
let mut inner=pair.into_inner();
let pair=safe_unwrap!(inner.next(),"Enum Specifier");
match pair.as_rule() {
Rule::enum_list => Ok(Self::Full(None, Box::new(EnumeratorList::take(pair)?))), Rule::tok_ident => {
let ident=Identifier::take(pair)?;
if let Some(pair)=inner.next() { Ok(Self::Full(Some(ident), Box::new(EnumeratorList::take(pair)?))) } else { Ok(Self::Decl(ident)) } },
_ => Err(rule_mismatch!(pair))
}
},
_ => Err(rule_mismatch!(pair,enum_spec))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct EnumeratorList(pub NonEmptyVec<Enumerator>); list_ast!(EnumeratorList : Enumerator where enum_list => enumerator);
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Enumerator {
Const(EnumConst), ConstWithVal(EnumConst,Box<ConstExpr>) }
impl AST for Enumerator {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::enumerator => {
let mut inner=pair.into_inner();
let enum_const=EnumConst::take(safe_unwrap!(inner.next(),"Enumerator"))?;
if let Some(const_expr)=inner.next() { Ok(Self::ConstWithVal(enum_const, Box::new(ConstExpr::take(const_expr)?))) } else { Ok(Self::Const(enum_const)) } },
_ => Err(rule_mismatch!(pair,enumerator))
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct EnumConst(pub Identifier);
impl AST for EnumConst {
fn take(pair: Pair<Rule>) -> Result<Self> {
match pair.as_rule() {
Rule::enum_const => {
let pair=safe_unwrap!(pair.into_inner().next(),"Enum Constant");
match pair.as_rule() {
Rule::tok_ident => Ok(Self(Identifier::take(pair)?)),
_ => Err(rule_mismatch!(pair,tok_ident))
}
},
_ => Err(rule_mismatch!(pair,enum_const))
}
}
}