[llvm] [llvm-lit] Support curly brace syntax in lit internal shell (PR #102829)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 11 13:47:24 PDT 2024
https://github.com/connieyzhu updated https://github.com/llvm/llvm-project/pull/102829
>From 01e06397c138a42516f65e16782eb069651b29fa Mon Sep 17 00:00:00 2001
From: Connie Zhu <connieyzhu at google.com>
Date: Sun, 11 Aug 2024 20:41:21 +0000
Subject: [PATCH] [llvm-lit] Initial draft of curly brace implementation
This is a draft of the parsing implementation to support curly brace
syntax in lit's internal shell.
---
llvm/utils/lit/lit/ShCommands.py | 5 +++--
llvm/utils/lit/lit/ShUtil.py | 36 +++++++++++++++++++++++++++++---
llvm/utils/lit/lit/TestRunner.py | 2 +-
3 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/llvm/utils/lit/lit/ShCommands.py b/llvm/utils/lit/lit/ShCommands.py
index 68655a41d7934b..392e05aaabdcd4 100644
--- a/llvm/utils/lit/lit/ShCommands.py
+++ b/llvm/utils/lit/lit/ShCommands.py
@@ -92,14 +92,15 @@ def toShell(self, file, pipefail=False):
class Seq:
- def __init__(self, lhs, op, rhs):
+ def __init__(self, lhs, op, rhs, seq_type):
assert op in (";", "&", "||", "&&")
self.op = op
self.lhs = lhs
self.rhs = rhs
+ self.type = seq_type
def __repr__(self):
- return "Seq(%r, %r, %r)" % (self.lhs, self.op, self.rhs)
+ return "Seq(%r, %r, %r, %r)" % (self.lhs, self.op, self.rhs, self.type)
def __eq__(self, other):
if not isinstance(other, Seq):
diff --git a/llvm/utils/lit/lit/ShUtil.py b/llvm/utils/lit/lit/ShUtil.py
index fa13167cad1be5..b835abe5a48ec6 100644
--- a/llvm/utils/lit/lit/ShUtil.py
+++ b/llvm/utils/lit/lit/ShUtil.py
@@ -157,7 +157,11 @@ def lex_one_token(self):
lex_one_token - Lex a single 'sh' token."""
c = self.eat()
+ if c == "{" or c == "}":
+ return (c,)
if c == ";":
+ if self.maybe_eat("}") or (self.maybe_eat(" ") and self.maybe_eat("}")):
+ return("}",)
return (c,)
if c == "|":
if self.maybe_eat("|"):
@@ -200,6 +204,8 @@ def __init__(self, data, win32Escapes=False, pipefail=False):
self.data = data
self.pipefail = pipefail
self.tokens = ShLexer(data, win32Escapes=win32Escapes).lex()
+ self.brace_stack = []
+ self.brace_dict = {'{': '}'}
def lex(self):
for item in self.tokens:
@@ -255,18 +261,42 @@ def parse_pipeline(self):
self.lex()
commands.append(self.parse_command())
return Pipeline(commands, negate, self.pipefail)
+
+
+ # {echo foo; echo bar;} && echo hello
+ # echo hello && {echo foo; echo bar}
+
+ def parse(self, seq_type):
+ lhs = None
+ if isinstance(self.look(), tuple):
+ brace = self.lex()
+ self.brace_stack.append(brace)
+ if brace[0] == '{':
+ lhs = self.parse(('{', '}'))
+ else:
+ raise ValueError("syntax error near unexpected token %r" % brace[0])
- def parse(self):
- lhs = self.parse_pipeline()
+ else:
+ lhs = self.parse_pipeline()
while self.look():
operator = self.lex()
assert isinstance(operator, tuple) and len(operator) == 1
+ if operator == self.brace_dict[self.brace_stack.peek()]:
+ break
+
if not self.look():
raise ValueError("missing argument to operator %r" % operator[0])
# FIXME: Operator precedence!!
- lhs = Seq(lhs, operator[0], self.parse_pipeline())
+ if isinstance(self.look(), tuple):
+ lhs = self.parse(('{', '}'))
+ else:
+ lhs = Seq(lhs, operator[0], self.parse_pipeline(), seq_type)
+ seq_type = None
+
+ if not stack.empty():
+ raise ValueError("missing token to %r" % stack.peek())
return lhs
diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py
index da7fa86fd39173..e5b484dbc62e87 100644
--- a/llvm/utils/lit/lit/TestRunner.py
+++ b/llvm/utils/lit/lit/TestRunner.py
@@ -1056,7 +1056,7 @@ def executeScriptInternal(
ln = command
try:
cmds.append(
- ShUtil.ShParser(ln, litConfig.isWindows, test.config.pipefail).parse()
+ ShUtil.ShParser(ln, litConfig.isWindows, test.config.pipefail).parse(None)
)
except:
raise ScriptFatal(
More information about the llvm-commits
mailing list