public static Int32 Parse(List<Token> src, Int32 begin, out Declr declr)
    {
        List<TypeModifier> modifiers;
        begin = Parser.ParseSequence(src, begin, out modifiers,

            // [pointer]?
            Parser.GetOptionalParser(new List<PointerModifier>(), _pointer.Parse),

            // [direct_abstract_declarator]?
            Parser.GetOptionalParser(new Declr("", new List<TypeModifier>()), _direct_abstract_declarator.Parse),

            (List<PointerModifier> ptr_modifiers, Declr abst_declr) => abst_declr.declr_modifiers.Concat(ptr_modifiers).ToList()
        );

        // make sure the list is non-empty
        if (begin != -1 && modifiers.Any()) {
            declr = new Declr("", modifiers);
            return begin;
        } else {
            declr = null;
            return -1;
        }
    }
    // '(' declarator ')'
    //
    public static Int32 ParseDeclarator(List<Token> src, Int32 begin, out Declr declr)
    {
        if (!Parser.EatOperator(src, ref begin, OperatorVal.LPAREN)) {
            declr = null;
            return -1;
        }

        if ((begin = _declarator.Parse(src, begin, out declr)) == -1) {
            declr = null;
            return -1;
        }

        if (!Parser.EatOperator(src, ref begin, OperatorVal.RPAREN)) {
            declr = null;
            return -1;
        }

        return begin;
    }
    // Parse direct declarator
    //
    public static Int32 Parse(List<Token> src, Int32 begin, out Declr declr)
    {
        String name;
        List<TypeModifier> modifiers = new List<TypeModifier>();

        // 1. match: id | '(' declarator ')'
        // 1.1. try: '(' declarator ')'
        Int32 current;
        if ((current = ParseDeclarator(src, begin, out declr)) != -1) {
            name = declr.name;
            modifiers = new List<TypeModifier>(declr.declr_modifiers);
        } else {
            // if fail, 1.2. try id
            name = Parser.GetIdentifierValue(src[begin]);
            if (name == null) {
                declr = null;
                return -1;
            }
            current = begin + 1;
        }

        List<TypeModifier> more_modifiers;
        current = Parser.ParseList(src, current, out more_modifiers, ParseSuffixModifier);
        modifiers.AddRange(more_modifiers);

        declr = new Declr(name, modifiers);
        return current;
    }
    public static Int32 Parse(List<Token> src, Int32 begin, out Declr declr)
    {
        List<TypeModifier> modifiers;

        // 1. match modifier | '(' abstract_declarator ')'
        // 1.1 try '(' abstract_declarator ')'
        Int32 current = ParseAbstractDeclarator(src, begin, out declr);
        if (current != -1) {
            modifiers = new List<TypeModifier>(declr.declr_modifiers);
        } else {
            // if fail, 1.2. try modifier
            TypeModifier modifier;
            if ((current = _direct_declarator.ParseSuffixModifier(src, begin, out modifier)) == -1) {
                declr = null;
                return -1;
            }
            modifiers = new List<TypeModifier> { modifier };
        }

        // now match modifiers
        List<TypeModifier> more_modifiers;
        current = Parser.ParseList(src, current, out more_modifiers, _direct_declarator.ParseSuffixModifier);
        modifiers.AddRange(more_modifiers);

        declr = new Declr("", modifiers);
        return current;
    }
    public static Int32 Parse(List<Token> src, Int32 begin, out Declr declr)
    {
        return Parser.ParseSequence(
            src, begin, out declr,

            // [pointer]?
            Parser.GetOptionalParser(new List<PointerModifier>(), _pointer.Parse),

            // direct_declarator
            _direct_declarator.Parse,

            (List<PointerModifier> pointer_modifiers, Declr direct_declr) => {
                String name = direct_declr.name;
                List<TypeModifier> modifiers = new List<TypeModifier>(direct_declr.declr_modifiers);
                modifiers.AddRange(pointer_modifiers);
                return new Declr(name, modifiers);
            }
        );
    }
 public static Int32 Parse(List<Token> src, Int32 begin, out Declr declr)
 {
     return _declarator.Parse(src, begin, out declr);
 }
 public TypeName(DeclnSpecs specs, Declr declr) {
     this.specs = specs;
     this.declr = declr;
 }
 public InitDeclr(Declr declr, Option<Initr> initr) {
     this.declr = declr;
     this.initr = initr;
 }
 public FuncDef(DeclnSpecs specs, Declr declr, CompoundStmt stmt)
 {
     this.specs = specs;
     this.declr = declr;
     this.stmt = stmt;
 }