From 6c1abb2dee991d84357776dfe09223f9c9ebe5b3 Mon Sep 17 00:00:00 2001 From: Vidar Holen Date: Thu, 30 Jun 2016 10:01:03 -0700 Subject: [PATCH] Performance: make readDollarExpr fail early if no $ --- ShellCheck/Parser.hs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ShellCheck/Parser.hs b/ShellCheck/Parser.hs index 2023157..6539975 100644 --- a/ShellCheck/Parser.hs +++ b/ShellCheck/Parser.hs @@ -1328,7 +1328,12 @@ prop_readDollarExpression1 = isOk readDollarExpression "$(((1) && 3))" prop_readDollarExpression2 = isWarning readDollarExpression "$(((1)) && 3)" prop_readDollarExpression3 = isWarning readDollarExpression "$((\"$@\" &); foo;)" readDollarExpression :: Monad m => SCParser m Token -readDollarExpression = arithmetic <|> readDollarExpansion <|> readDollarBracket <|> readDollarBraceCommandExpansion <|> readDollarBraced <|> readDollarVariable +readDollarExpression = do + -- The grammar should have been designed along the lines of readDollarExpr = char '$' >> stuff, but + -- instead, each subunit parses its own $. This results in ~7 1-3 char lookaheads instead of one 1-char. + -- Instead of optimizing the grammar, here's a green cut that decreases shellcheck runtime by 10%: + lookAhead $ char '$' + arithmetic <|> readDollarExpansion <|> readDollarBracket <|> readDollarBraceCommandExpansion <|> readDollarBraced <|> readDollarVariable where arithmetic = readAmbiguous "$((" readDollarArithmetic readDollarExpansion (\pos -> parseNoteAt pos WarningC 1102 "Shells disambiguate $(( differently or not at all. If the first $( should start command substitution, add a space after it.")