From nobody Mon Feb 9 17:59:07 2026 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) 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=temperror (zoho.com: Error in retrieving data from DNS) 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 1548412519125700.0306555641589; Fri, 25 Jan 2019 02:35:19 -0800 (PST) Received: from localhost ([127.0.0.1]:41628 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gmyp8-0003e6-2E for importer@patchew.org; Fri, 25 Jan 2019 05:34:58 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58227) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gmyOr-0007gs-7I for qemu-devel@nongnu.org; Fri, 25 Jan 2019 05:07:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gmyOm-0001sw-5U for qemu-devel@nongnu.org; Fri, 25 Jan 2019 05:07:49 -0500 Received: from mail-wr1-x433.google.com ([2a00:1450:4864:20::433]:46161) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gmyOl-0001pX-Qm for qemu-devel@nongnu.org; Fri, 25 Jan 2019 05:07:43 -0500 Received: by mail-wr1-x433.google.com with SMTP id l9so9579392wrt.13 for ; Fri, 25 Jan 2019 02:07:43 -0800 (PST) Received: from 640k.lan ([93.56.166.5]) by smtp.gmail.com with ESMTPSA id p4sm88048455wrs.74.2019.01.25.02.07.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 25 Jan 2019 02:07:41 -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=oDql9niKUpXpXD428wkAUaYAXEC0/5RltfODN/kNrIA=; b=CoBkc8s80/vSutJG/LCyoAJ8RRynlbGSHPcC7FPokoSgwjDNiD90zX40sF8wGKGiFi 9EfSbcUXhLgXHQizH2LVUzWqW2uk+9PQWozjZyYM7BxTtDSDFOvQEV+sctcGq1D1Mw9D EXNMVEbKd4pe/dZVMLZpSurodCFn5PP2YNb+30NxmBM4phP652TWjYfgQBwKKNffe72w 03tN3k7Vi5mLJyLQFTbbfuw7fDjGXSpfPfeQZQaRJLXGFMIIi6OIeN/hy878YWNmb1uL OCH1c4H+PRCGyX5V5gvoxPVTmEWj1TAvrX8xxYlBXhyRrQ2eidyfMpyvlHPafDJ1uRmp 9QbQ== 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=oDql9niKUpXpXD428wkAUaYAXEC0/5RltfODN/kNrIA=; b=WD3Oyc8MktXfrAewQ2AC96sN9MOXemh+xH4yMRywCMehgbBUL3+ZeVEQ1zHz2k2wNG PmVl56gPTbc+mRAZRD2tqLHZeyc9k+x7RHcvZDmL+CRv93MD4SVaPsnNxbFTePsc55yf byJAR2TsqKuSGxSNyTV6fOT/TeNkSnFXrX0wnvHXOrAP2rlcJLnxy4ROHiH+C3zhcp2u YSmj7wSZwrkTVpKHfUbg1WeP81xn4xy4Cq/FJxJ3qM8ZLN9nykREwrHDh7NBQXquA/d6 tn3OoRe+SWqKKH4DGT07F/ohxmL3Lsz6y6wny21wEfkxnrkBLfzey6d5P8Wn02iFoF9/ wBHQ== X-Gm-Message-State: AJcUukfGeB5zBoB65k6ZU9wCM1o349Fxx83kyR/HR9cXZEPIO2eGNKdt l9jHGdtBibokF1UGTgNscU1WKyW7 X-Google-Smtp-Source: ALg8bN6qYW1eJ642bQMyyjWJgdbRVFnL0/ANrkq7eWjlJztbufYyZHFaOs0Ch3+29R4sounsZ4EnEQ== X-Received: by 2002:adf:81c4:: with SMTP id 62mr10157020wra.266.1548410862390; Fri, 25 Jan 2019 02:07:42 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 25 Jan 2019 11:06:48 +0100 Message-Id: <1548410831-19553-30-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1548410831-19553-1-git-send-email-pbonzini@redhat.com> References: <1548410831-19553-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::433 Subject: [Qemu-devel] [PATCH 29/52] 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@intel.com, 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 | 116 +++++++++++++++++++++++++++++++++++++++++++----= ---- 1 file changed, 98 insertions(+), 18 deletions(-) diff --git a/scripts/minikconf.py b/scripts/minikconf.py index 4a1fe09..eeecac1 100644 --- a/scripts/minikconf.py +++ b/scripts/minikconf.py @@ -27,11 +27,84 @@ __all__ =3D [ 'KconfigParserError', 'KconfigData', 'Kco= nfigParser' ] # ------------------------------------------- =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 @@ -49,26 +122,28 @@ 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 # ------------------------------------------- # KconfigParser implements a recursive descent parser for (simplified) @@ -229,31 +304,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 @@ -422,4 +500,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