From nobody Sun Oct 5 01:45:08 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 (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 155172643581614.161715346297115; Mon, 4 Mar 2019 11:07:15 -0800 (PST) Received: from localhost ([127.0.0.1]:59307 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h0sve-0007BI-IE for importer@patchew.org; Mon, 04 Mar 2019 14:07:10 -0500 Received: from eggs.gnu.org ([209.51.188.92]:45654) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h0sCO-0001lE-AJ for qemu-devel@nongnu.org; Mon, 04 Mar 2019 13:20:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h0sCM-0003gC-Ok for qemu-devel@nongnu.org; Mon, 04 Mar 2019 13:20:24 -0500 Received: from mail-wm1-x32f.google.com ([2a00:1450:4864:20::32f]:35403) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1h0sCM-0003eH-GF for qemu-devel@nongnu.org; Mon, 04 Mar 2019 13:20:22 -0500 Received: by mail-wm1-x32f.google.com with SMTP id y15so144129wma.0 for ; Mon, 04 Mar 2019 10:20:22 -0800 (PST) Received: from 640k.lan ([93.56.166.5]) by smtp.gmail.com with ESMTPSA id q5sm8371364wrn.43.2019.03.04.10.20.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 04 Mar 2019 10:20:20 -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=xXjALrAqXDRv0kzUZR34KdC14OmcAsIaHvlc3UuW4Y4=; b=qgzj2FcOrq9C7HkzQZ4Be6aUT6rT+J90bo+ILZTgMT7OqxnXRIqAt28G2YLtze5Bu1 39E+kp54zAxKSSXOdf/zrcCH/3tssokM41NJupEAEichopoMzC6OsAXP02feOT6R/cO1 72Eit6Ldfo4cPfla7Bk6AITcuZA2P/DOuRPvziD3CYuNluDndWj9SADEd83AA4ep/fdC RwyoJUGNs1cs9lTI+79sVezsqWFkeKU7u1n5nEtQX9YacdEQBoz3zv7Fq437Gm5LzoSh z2qhcN4xo2iPwnLhWctadskJAkENIhS2MDkyRbbfRhjIAUuXit0UOV6eV9mUUqivBmVq 3OxA== 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=xXjALrAqXDRv0kzUZR34KdC14OmcAsIaHvlc3UuW4Y4=; b=QuLepKug6dIqbub1EQA5nx+mU/YuknffWUI/fU1WjWzea1VXzRreKW4hIvAqr4PwhX KvZeMgySMFYETJUuuxQ4WGVDXm7MsLnj3Gs6ri/bx5bW56LbQKixGgapxpUmGn8XQ5f4 oRhxYvK7EskKiXmUU764IgC9bNTf+GOIx0ftxAro4SQ+M3lC4QqAoNCfA4nXCsTK83P6 s3JaMzWkp3bf1GTTVB1vhby7AdRzrKT98GoxYbpghEN599xpkiNZhxN+HPvi+MjXs9EH NN1jcbCD1Uq6iH19utrx0/wohSCY2+jYwJieHT1IcWKCMQ+h464vbjPyiL+pYdxznEH+ awig== X-Gm-Message-State: APjAAAVdh4k+XQGwifAxraU1Dytf7l75qLVpojIUFFuFLYBT6dszY3Iz B74nzIgoXno1FAvd6/Fjvgt6iM4m X-Google-Smtp-Source: APXvYqyJkOs+xWKSZypyUhB/ngknvlfeRqoG2E1aoCX7K/o/XrJzCiDk0zqcTYNGytGTjVLBOWP56w== X-Received: by 2002:a1c:d049:: with SMTP id h70mr257164wmg.81.1551723621005; Mon, 04 Mar 2019 10:20:21 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Mon, 4 Mar 2019 19:19:25 +0100 Message-Id: <1551723614-1823-6-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1551723614-1823-1-git-send-email-pbonzini@redhat.com> References: <1551723614-1823-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::32f Subject: [Qemu-devel] [PULL 05/54] 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: Yang Zhong , thuth@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 fd75d96..f0cc3b9 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