lib/grammar.js
function checkStructMember(structname, obj, callback, root) {
    var membername = obj.name.name;

    if (!isVarString(membername)) {
        callback(false, structname + '.' + membername + ': The first letter should be lowercase.');

        return false;
    }

    if (!base.isType(obj.type, root)) {
        callback(false, structname + '.' + membername + ': ' + obj.type + ' not defined.');

        return false;
    }

    if (obj.type == 'time') {
        if (obj.hasOwnProperty('val')) {
            if (typeof(obj.val) == 'object') {
                if (obj.val.type == 'NULL') {
                    return true;
                }
                else if (obj.val.type == 'time' && obj.val.val == 'NOW') {
                    return true;
                }
            }

            callback(false, structname + '.' + membername + ': default is not NULL or NOW.');

            return false;
        }
    }
    else if (obj.type == 'int') {
        if (obj.hasOwnProperty('val')) {
            if (typeof(obj.val) == 'object') {
                if (obj.val.type == 'int' && obj.val.val == 'AUTOINC') {
                    if (obj.type2 != 'primary') {
                        callback(false, structname + '.' + membername + ': AUTOINC is primary.');

                        return false;
                    }
                }
            }
        }
    }

    if (obj.type2 == 'expand') {
        if (obj.hasOwnProperty('expand')) {
            if (!base.isEnum(obj.expand, root)) {
                callback(false, structname + '.' + membername + ': expand need enum!.');

                return false;
            }
        }
        else {
            var cobj = base.getGlobalObj(obj.type, root);
            if (cobj == undefined) {
                callback(false, structname + '.' + membername + ': expand fail!.');

                return false;
            }

            var structobj = base.getGlobalObj(structname, root);
            for (var i = 0; i < cobj.val.length; ++i) {
                if (base.hasMemberEx(cobj.val[i].name.name, obj.type, structobj, root)) {
                    callback(false, structname + '.' + membername + '.' + cobj.val[i].name.name + ': expand err(duplication of name).');

                    return false;
                }
            }
        }
    }

    if (obj.type2 == 'repeated') {
        if (obj.hasOwnProperty('memberkey')) {
            if (!(base.isStruct(obj.type, root) || base.isStatic(obj.type, root))) {
                callback(false, structname + '.' + membername + ': repeated object must be struct.');

                return false;
            }

            if (!base.hasMember2(obj.memberkey, base.getGlobalObj(obj.type, root), root)) {
                callback(false, structname + '.' + membername + ': repeated key(' + obj.memberkey + ') not defined in ' + obj.type + '.');

                return false;
            }
        }
    }

    return true;
}
function checkStructMember(structname, obj, callback, root) {
    var membername = obj.name.name;

    if (!isVarString(membername)) {
        callback(false, structname + '.' + membername + ': The first letter should be lowercase.');

        return false;
    }

    if (!base.isType(obj.type, root)) {
        callback(false, structname + '.' + membername + ': ' + obj.type + ' not defined.');

        return false;
    }

    if (obj.type == 'time') {
        if (obj.hasOwnProperty('val')) {
            if (typeof(obj.val) == 'object') {
                if (obj.val.type == 'NULL') {
                    return true;
                }
                else if (obj.val.type == 'time' && obj.val.val == 'NOW') {
                    return true;
                }
            }

            callback(false, structname + '.' + membername + ': default is not NULL or NOW.');

            return false;
        }
    }
    else if (obj.type == 'int') {
        if (obj.hasOwnProperty('val')) {
            if (typeof(obj.val) == 'object') {
                if (obj.val.type == 'int' && obj.val.val == 'AUTOINC') {
                    if (obj.type2 != 'primary') {
                        callback(false, structname + '.' + membername + ': AUTOINC is primary.');

                        return false;
                    }
                }
            }
        }
    }

    if (obj.type2 == 'expand') {
        if (obj.hasOwnProperty('expand')) {
            if (!base.isEnum(obj.expand, root)) {
                callback(false, structname + '.' + membername + ': expand need enum!.');

                return false;
            }
        }
        else {
            var cobj = base.getGlobalObj(obj.type, root);
            if (cobj == undefined) {
                callback(false, structname + '.' + membername + ': expand fail!.');

                return false;
            }

            var structobj = base.getGlobalObj(structname, root);
            for (var i = 0; i < cobj.val.length; ++i) {
                if (base.hasMemberEx(cobj.val[i].name.name, obj.type, structobj, root)) {
                    callback(false, structname + '.' + membername + '.' + cobj.val[i].name.name + ': expand err(duplication of name).');

                    return false;
                }
            }
        }
    }

    if (obj.type2 == 'repeated') {
        if (obj.hasOwnProperty('memberkey')) {
            if (!(base.isStruct(obj.type, root) || base.isStatic(obj.type, root))) {
                callback(false, structname + '.' + membername + ': repeated object must be struct.');

                return false;
            }

            if (!base.hasMember2(obj.memberkey, base.getGlobalObj(obj.type, root), root)) {
                callback(false, structname + '.' + membername + ': repeated key(' + obj.memberkey + ') not defined in ' + obj.type + '.');

                return false;
            }
        }
    }

    return true;
}
function checkStructMember ( structname , obj , callback , root ) { var membername = obj . name . name ; if ( ! isVarString ( membername ) ) { callback ( false , structname + '.' + membername + ': The first letter should be lowercase.' ) ; return false ; } if ( ! base . isType ( obj . type , root ) ) { callback ( false , structname + '.' + membername + ': ' + obj . type + ' not defined.' ) ; return false ; } if ( obj . type == 'time' ) { if ( obj . hasOwnProperty ( 'val' ) ) { if ( typeof ( obj . val ) == 'object' ) { if ( obj . val . type == 'NULL' ) { return true ; } else if ( obj . val . type == 'time' && obj . val . val == 'NOW' ) { return true ; } } callback ( false , structname + '.' + membername + ': default is not NULL or NOW.' ) ; return false ; } } else if ( obj . type == 'int' ) { if ( obj . hasOwnProperty ( 'val' ) ) { if ( typeof ( obj . val ) == 'object' ) { if ( obj . val . type == 'int' && obj . val . val == 'AUTOINC' ) { if ( obj . type2 != 'primary' ) { callback ( false , structname + '.' + membername + ': AUTOINC is primary.' ) ; return false ; } } } } } if ( obj . type2 == 'expand' ) { if ( obj . hasOwnProperty ( 'expand' ) ) { if ( ! base . isEnum ( obj . expand , root ) ) { callback ( false , structname + '.' + membername + ': expand need enum!.' ) ; return false ; } } else { var cobj = base . getGlobalObj ( obj . type , root ) ; if ( cobj == undefined ) { callback ( false , structname + '.' + membername + ': expand fail!.' ) ; return false ; } var structobj = base . getGlobalObj ( structname , root ) ; for ( var i = 0 ; i < cobj . val . length ; ++ i ) { if ( base . hasMemberEx ( cobj . val [ i ] . name . name , obj . type , structobj , root ) ) { callback ( false , structname + '.' + membername + '.' + cobj . val [ i ] . name . name + ': expand err(duplication of name).' ) ; return false ; } } } } if ( obj . type2 == 'repeated' ) { if ( obj . hasOwnProperty ( 'memberkey' ) ) { if ( ! ( base . isStruct ( obj . type , root ) || base . isStatic ( obj . type , root ) ) ) { callback ( false , structname + '.' + membername + ': repeated object must be struct.' ) ; return false ; } if ( ! base . hasMember2 ( obj . memberkey , base . getGlobalObj ( obj . type , root ) , root ) ) { callback ( false , structname + '.' + membername + ': repeated key(' + obj . memberkey + ') not defined in ' + obj . type + '.' ) ; return false ; } } } return true ; }
callback(isok, err)
callback ( isok err )