From 1b63adfba840d50cc7c0f7ed409a9dbf2498c002 Mon Sep 17 00:00:00 2001 From: Ronald Brill Date: Sat, 15 Apr 2023 13:42:13 +0200 Subject: [PATCH] try different ways of doing lookahead --- src/main/javacc/CSS3Parser.jj | 50 ++++++++++++++++++- .../cssparser/parser/CSS3ParserTest.java | 33 ++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/main/javacc/CSS3Parser.jj b/src/main/javacc/CSS3Parser.jj index 7995c10..e99f368 100644 --- a/src/main/javacc/CSS3Parser.jj +++ b/src/main/javacc/CSS3Parser.jj @@ -1108,7 +1108,11 @@ Selector selector() : { try { sel = simpleSelector(null, ' ') - ( LOOKAHEAD(2) comb = combinator() sel = simpleSelector(sel, comb) )* ( )* + ( + LOOKAHEAD(2) + /* LOOKAHEAD(combinator() ( | | | | | )) */ + /* LOOKAHEAD( { isCombinator() }) */ + comb = combinator() sel = simpleSelector(sel, comb) )* ( )* { return sel; } @@ -2429,3 +2433,47 @@ Boolean handleCaseInSensitive(Token t) throw toCSSParseException("invalidCaseInSensitivelyIdentifier", new String[] { s }, createLocator(t)); } + +JAVACODE +boolean isCombinator() +{ + Token token = getToken(1); + if (token.kind == EOF) { return false; } + + if (token.kind == S) { + token = getToken(2); + if (token.kind == EOF) { return false; } + + if (token.kind == PLUS || token.kind == GREATER || token.kind == TILDE) { + token = getToken(3); + if (token.kind == EOF) { return false; } + if (token.kind == S) { + token = getToken(4); + if (token.kind == EOF) { return false; } + } + } + + return token.kind == IDENT + || token.kind == ASTERISK + || token.kind == HASH + || token.kind == DOT + || token.kind == LSQUARE + || token.kind == COLON; + } + else if (token.kind == PLUS || token.kind == GREATER || token.kind == TILDE) { + token = getToken(2); + if (token.kind == EOF) { return false; } + if (token.kind == S) { + token = getToken(3); + if (token.kind == EOF) { return false; } + } + + return token.kind == IDENT + || token.kind == ASTERISK + || token.kind == HASH + || token.kind == DOT + || token.kind == LSQUARE + || token.kind == COLON; + } + return false; +} diff --git a/src/test/java/org/htmlunit/cssparser/parser/CSS3ParserTest.java b/src/test/java/org/htmlunit/cssparser/parser/CSS3ParserTest.java index d22429a..6a0cc06 100644 --- a/src/test/java/org/htmlunit/cssparser/parser/CSS3ParserTest.java +++ b/src/test/java/org/htmlunit/cssparser/parser/CSS3ParserTest.java @@ -4498,6 +4498,39 @@ public void doubleColonsPseudoClass() throws Exception { assertEquals("h1::link { color: red; }", rule.getCssText()); } + /** + * @throws Exception if the test fails + */ + @Test + public void performance() throws Exception { + for (int i = 0; i < 40; i++) { + realWorld("realworld/style.csx.css"); + realWorld("realworld/compass-homestyle.css"); + realWorld("realworld/www.css"); + realWorld("realworld/home.built.css"); + realWorld("realworld/load.php.css"); + realWorld("realworld/normalize.css"); + realWorld("realworld/cargo.css"); + realWorld("realworld/blueprint/screen.css"); + realWorld("realworld/blueprint/print.css"); + realWorld("realworld/blueprint/ie.css"); + realWorld("realworld/bootstrap_3_3_7_min.css"); + realWorld("realworld/bootstrap_4_0_0.css"); + realWorld("realworld/bootstrap_4_0_0_min.css"); + realWorld("realworld/style-V5-11.css"); + realWorld("realworld/all.css"); + } + } + + private static final CSSOMParser p = new CSSOMParser(); + + private void realWorld(final String resourceName) throws Exception { + final InputStream is = getClass().getClassLoader().getResourceAsStream(resourceName); + assertNotNull(is); + + final InputSource css = new InputSource(new InputStreamReader(is, StandardCharsets.UTF_8)); + p.parseStyleSheet(css, null); + } // // /** // * @throws Exception if any error occurs