From nobody Fri Dec 19 07:41:46 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1549563317594112.00968296925339; Thu, 7 Feb 2019 10:15:17 -0800 (PST) Received: from localhost ([127.0.0.1]:44676 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1groCd-0007Ak-FX for importer@patchew.org; Thu, 07 Feb 2019 13:15:11 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57332) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1grnvt-0001vl-5C for qemu-devel@nongnu.org; Thu, 07 Feb 2019 12:57:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1grnvr-0002Cw-K5 for qemu-devel@nongnu.org; Thu, 07 Feb 2019 12:57:53 -0500 Received: from mail-wr1-x42e.google.com ([2a00:1450:4864:20::42e]:42492) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1grnvr-00024e-B6 for qemu-devel@nongnu.org; Thu, 07 Feb 2019 12:57:51 -0500 Received: by mail-wr1-x42e.google.com with SMTP id q18so796758wrx.9 for ; Thu, 07 Feb 2019 09:57:41 -0800 (PST) Received: from 640k.lan ([93.56.166.5]) by smtp.gmail.com with ESMTPSA id q12sm12708982wmf.2.2019.02.07.09.57.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Feb 2019 09:57:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=IDz5+AjM9ntwURv6j4a/LPDTIE0YEl+7NnnpAPIGCW4=; b=ciSiKV3WlJdR35H2Zw0K7BvLpR2Aqa99OZVWFH8+a2f1H/TDsiBBjWsJg3lcNrsAm9 Fjd+CwcudvUHjsU//A/np0ES6HvYN9+3RYtdaFBb6HhLNT/rr1KMcZU1+4O8RA4wXC+J mFE8ChP1CDYy0FMh6Wxn73qGOueRHePaVfNHQ0owY+ZeVUS5hb8xNsl3He+M59OWaLoh Nr6Q+zc4uSpHYQVO7f/XEUDQSSAND69r2MuXBBOpQBU1QfFGIJ4adFnwgLUwPL18MODR UetugcNsyt0yS0I1k1zBsA/l7pYWrQ7bvrBQfEoOUpUitAFEfAKmVaaU5yDdZvKyrlga ECgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=IDz5+AjM9ntwURv6j4a/LPDTIE0YEl+7NnnpAPIGCW4=; b=mUmRojgKxo0f3OK2EzQL2oVVqOxJilZ401OjExACj8VVq55ENMeBjp2AQ3LW68YdGM ohuKGhDageMhpzMxiDOYtlWBkFnkEpfSMfq1IeNbADbu2WlkXywdqRK4rCKBpCOZANRF 3hNKokpOQaHbQ4JJ/SBJ70ttWX8HX9wRMo7dpdT8W6Mk/PKbFMrQjngMgPOaI4wHraJ7 llA+Pygsg7Yi1e7xBgbXOMaQ7zK0D6KNGSwN9frgXxbg6UEGar9OUiUPMgWH5d6KriBq lnz6r2V/mnEYgluzCRcMCf06gKAD0VUlxq0E4mVxYhVocx3kgBsFk6tGF7owXS2yvzoQ m8+A== X-Gm-Message-State: AHQUAubEFA+r5ZpAgZfqZvpybmO6ZuI6GtZDAn+Ujvo4+hzKtscJjyTY JJwzYmbawxJF93ogQaQuPoqj7Ybh X-Google-Smtp-Source: AHgI3IYz4QI47KmUARKyDCnFkMwMwmCP9Mj17qfuP4MAJ+XyTM2GV6IgCfec4cSthbHa0joaGofB/g== X-Received: by 2002:adf:dfd1:: with SMTP id q17mr13827538wrn.27.1549562259630; Thu, 07 Feb 2019 09:57:39 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Thu, 7 Feb 2019 18:56:45 +0100 Message-Id: <1549562254-41157-3-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1549562254-41157-1-git-send-email-pbonzini@redhat.com> References: <1549562254-41157-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::42e Subject: [Qemu-devel] [PATCH 02/51] minikconfig: add AST X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, philmd@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add Python classes that represent the Kconfig abstract syntax tree. The abstract syntax tree is stored as a list of clauses. For example: config FOO depends on BAR select BAZ is represented as three clauses: FOO depends on BAR FOO default n select BAZ if FOO Signed-off-by: Paolo Bonzini Message-Id: <20190123065618.3520-24-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- scripts/minikconf.py | 121 +++++++++++++++++++++++++++++++++++++++++++----= ---- 1 file changed, 102 insertions(+), 19 deletions(-) diff --git a/scripts/minikconf.py b/scripts/minikconf.py index 8861a32..d74b9df 100644 --- a/scripts/minikconf.py +++ b/scripts/minikconf.py @@ -31,11 +31,84 @@ def debug_print(*args): # ------------------------------------------- =20 class KconfigData: + class Expr: + def __and__(self, rhs): + return KconfigData.AND(self, rhs) + def __or__(self, rhs): + return KconfigData.OR(self, rhs) + def __invert__(self): + return KconfigData.NOT(self) + + class AND(Expr): + def __init__(self, lhs, rhs): + self.lhs =3D lhs + self.rhs =3D rhs + def __str__(self): + return "(%s && %s)" % (self.lhs, self.rhs) + + class OR(Expr): + def __init__(self, lhs, rhs): + self.lhs =3D lhs + self.rhs =3D rhs + def __str__(self): + return "(%s || %s)" % (self.lhs, self.rhs) + + class NOT(Expr): + def __init__(self, lhs): + self.lhs =3D lhs + def __str__(self): + return "!%s" % (self.lhs) + + class Var(Expr): + def __init__(self, name): + self.name =3D name + self.value =3D None + def __str__(self): + return self.name + + class Clause: + def __init__(self, dest): + self.dest =3D dest + + class AssignmentClause(Clause): + def __init__(self, dest, value): + KconfigData.Clause.__init__(self, dest) + self.value =3D value + def __str__(self): + return "%s=3D%s" % (self.dest, 'y' if self.value else 'n') + + class DefaultClause(Clause): + def __init__(self, dest, value, cond=3DNone): + KconfigData.Clause.__init__(self, dest) + self.value =3D value + self.cond =3D cond + def __str__(self): + value =3D 'y' if self.value else 'n' + if self.cond is None: + return "config %s default %s" % (self.dest, value) + else: + return "config %s default %s if %s" % (self.dest, value, s= elf.cond) + + class DependsOnClause(Clause): + def __init__(self, dest, expr): + KconfigData.Clause.__init__(self, dest) + self.expr =3D expr + def __str__(self): + return "config %s depends on %s" % (self.dest, self.expr) + + class SelectClause(Clause): + def __init__(self, dest, cond): + KconfigData.Clause.__init__(self, dest) + self.cond =3D cond + def __str__(self): + return "select %s if %s" % (self.dest, self.cond) + def __init__(self): self.previously_included =3D [] self.incl_info =3D None self.defined_vars =3D set() - self.referenced_vars =3D set() + self.referenced_vars =3D dict() + self.clauses =3D list() =20 # semantic analysis ------------- =20 @@ -53,29 +126,34 @@ class KconfigData: if (var in self.defined_vars): raise Exception('variable "' + var + '" defined twice') =20 - self.defined_vars.add(var) + self.defined_vars.add(var.name) =20 # var is a string with the variable's name. - # - # For now this just returns the variable's name itself. def do_var(self, var): - self.referenced_vars.add(var) - return var + if (var in self.referenced_vars): + return self.referenced_vars[var] + + var_obj =3D self.referenced_vars[var] =3D KconfigData.Var(var) + return var_obj =20 def do_assignment(self, var, val): - pass + self.clauses.append(KconfigData.AssignmentClause(var, val)) =20 def do_default(self, var, val, cond=3DNone): - pass + self.clauses.append(KconfigData.DefaultClause(var, val, cond)) =20 def do_depends_on(self, var, expr): - pass + self.clauses.append(KconfigData.DependsOnClause(var, expr)) =20 def do_select(self, var, symbol, cond=3DNone): - pass + cond =3D (cond & var) if cond is not None else var + self.clauses.append(KconfigData.SelectClause(symbol, cond)) =20 def do_imply(self, var, symbol, cond=3DNone): - pass + # "config X imply Y [if COND]" is the same as + # "config Y default y if X [&& COND]" + cond =3D (cond & var) if cond is not None else var + self.do_default(symbol, True, cond) =20 # ------------------------------------------- # KconfigParser implements a recursive descent parser for (simplified) @@ -237,31 +315,34 @@ class KconfigParser: def parse_primary(self): if self.tok =3D=3D TOK_NOT: self.get_token() - self.parse_primary() + val =3D ~self.parse_primary() elif self.tok =3D=3D TOK_LPAREN: self.get_token() - self.parse_expr() + val =3D self.parse_expr() if self.tok !=3D TOK_RPAREN: raise KconfigParserError(self, 'Expected ")"') self.get_token() elif self.tok =3D=3D TOK_ID: - self.parse_var() + val =3D self.parse_var() else: raise KconfigParserError(self, 'Expected "!" or "(" or identif= ier') + return val =20 # disj: primary (OR primary)* def parse_disj(self): - self.parse_primary() + lhs =3D self.parse_primary() while self.tok =3D=3D TOK_OR: self.get_token() - self.parse_primary() + lhs =3D lhs | self.parse_primary() + return lhs =20 # expr: disj (AND disj)* def parse_expr(self): - self.parse_disj() + lhs =3D self.parse_disj() while self.tok =3D=3D TOK_AND: self.get_token() - self.parse_disj() + lhs =3D lhs & self.parse_disj() + return lhs =20 # condition: IF expr # | empty @@ -438,4 +519,6 @@ class KconfigParser: =20 if __name__ =3D=3D '__main__': fname =3D len(sys.argv) > 1 and sys.argv[1] or 'Kconfig.test' - KconfigParser.parse(open(fname, 'r')) + data =3D KconfigParser.parse(open(fname, 'r')) + for i in data.clauses: + print i --=20 1.8.3.1