From 14a07f679a1ad1726445f363fee484e3b2d52884 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Tue, 23 Feb 2016 19:49:30 +0000 Subject: Move HTML path parsing rules into their own class --- .../org/zwobble/mammoth/styles/StyleMapParser.java | 103 --------------------- .../mammoth/styles/parsing/HtmlPathParser.java | 68 ++++++++++++++ .../zwobble/mammoth/styles/parsing/ListVar.java | 34 +++++++ .../zwobble/mammoth/styles/parsing/Parsing.java | 23 +++++ 4 files changed, 125 insertions(+), 103 deletions(-) create mode 100644 src/main/java/org/zwobble/mammoth/styles/parsing/HtmlPathParser.java create mode 100644 src/main/java/org/zwobble/mammoth/styles/parsing/ListVar.java create mode 100644 src/main/java/org/zwobble/mammoth/styles/parsing/Parsing.java (limited to 'src/main/java') diff --git a/src/main/java/org/zwobble/mammoth/styles/StyleMapParser.java b/src/main/java/org/zwobble/mammoth/styles/StyleMapParser.java index be0a268..1092353 100644 --- a/src/main/java/org/zwobble/mammoth/styles/StyleMapParser.java +++ b/src/main/java/org/zwobble/mammoth/styles/StyleMapParser.java @@ -1,110 +1,7 @@ package org.zwobble.mammoth.styles; -import com.google.common.collect.ImmutableList; import org.parboiled.BaseParser; -import org.parboiled.Parboiled; -import org.parboiled.Rule; -import org.parboiled.parserunners.ReportingParseRunner; -import org.parboiled.support.ParsingResult; -import org.parboiled.support.Var; - -import java.util.List; - -import static org.zwobble.mammoth.util.MammothLists.list; -import static org.zwobble.mammoth.util.MammothMaps.map; public class StyleMapParser extends BaseParser { - public static HtmlPath parseHtmlPath(String value) { - StyleMapParser parser = Parboiled.createParser(StyleMapParser.class); - ReportingParseRunner runner = new ReportingParseRunner<>(parser.HtmlPath()); - ParsingResult result = runner.run(value); - if (result.hasErrors()) { - // TODO: wrap in result - throw new RuntimeException("Parse error"); - } else { - return result.valueStack.peek(); - } - } - - Rule HtmlPath() { - ListVar elements = new ListVar<>(); - return Sequence(Optional(HtmlPathElements(elements)), EOI, push(new HtmlPath(elements.build()))); - } - - Rule HtmlPathElements(ListVar elements) { - Var element = new Var<>(); - return Sequence( - HtmlPathElement(element), - elements.append(element), - ZeroOrMore(Sequence(Whitespace(), Ch('>'), Whitespace(), HtmlPathElement(element), elements.append(element)))); - } - - Rule HtmlPathElement(Var element) { - ListVar tagNames = new ListVar<>(); - ListVar classNames = new ListVar<>(); - Var fresh = new Var<>(); - return Sequence( - TagNames(tagNames), - ClassNames(classNames), - Fresh(fresh), - element.set(new HtmlPathElement( - tagNames.build(), - classNames.isEmpty() ? map() : map("class", String.join(" ", classNames.build())), - !fresh.get()))); - } - - Rule TagNames(ListVar tagNames) { - return Sequence( - Identifier(), - tagNames.append(match()), - ZeroOrMore(Sequence("|", Identifier(), tagNames.append(match())))); - } - - Rule ClassNames(ListVar classNames) { - Var className = new Var<>(); - return ZeroOrMore(Sequence(ClassName(className), classNames.append(className))); - } - - Rule ClassName(Var className) { - return Sequence(".", Identifier(), className.set(match())); - } - - Rule Fresh(Var fresh) { - return Sequence(fresh.set(false), Optional(":fresh", fresh.set(true))); - } - - Rule Identifier() { - return Sequence( - FirstOf(CharRange('a', 'z'), CharRange('A', 'Z')), - ZeroOrMore(FirstOf(CharRange('a', 'z'), CharRange('A', 'Z'), CharRange('0', '9'), Ch('-'), Ch('_')))); - } - - Rule Whitespace() { - return ZeroOrMore(AnyOf(" \t")); - } - - class ListVar extends Var> { - boolean append(Var element) { - return append(element.get()); - } - - boolean append(T element) { - if (get() == null) { - set(ImmutableList.builder()); - } - return set(get().add(element)); - } - - public List build() { - if (get() == null) { - return list(); - } else { - return get().build(); - } - } - public boolean isEmpty() { - return get() == null; - } - } } diff --git a/src/main/java/org/zwobble/mammoth/styles/parsing/HtmlPathParser.java b/src/main/java/org/zwobble/mammoth/styles/parsing/HtmlPathParser.java new file mode 100644 index 0000000..18e1107 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/styles/parsing/HtmlPathParser.java @@ -0,0 +1,68 @@ +package org.zwobble.mammoth.styles.parsing; + +import org.parboiled.BaseParser; +import org.parboiled.Rule; +import org.parboiled.support.Var; +import org.zwobble.mammoth.styles.HtmlPath; +import org.zwobble.mammoth.styles.HtmlPathElement; + +import static org.zwobble.mammoth.util.MammothMaps.map; + +public class HtmlPathParser extends BaseParser { + public Rule HtmlPath() { + ListVar elements = new ListVar<>(); + return Sequence(Optional(HtmlPathElements(elements)), EOI, push(new HtmlPath(elements.build()))); + } + + Rule HtmlPathElements(ListVar elements) { + Var element = new Var<>(); + return Sequence( + HtmlPathElement(element), + elements.append(element), + ZeroOrMore(Sequence(Whitespace(), Ch('>'), Whitespace(), HtmlPathElement(element), elements.append(element)))); + } + + Rule HtmlPathElement(Var element) { + ListVar tagNames = new ListVar<>(); + ListVar classNames = new ListVar<>(); + Var fresh = new Var<>(); + return Sequence( + TagNames(tagNames), + ClassNames(classNames), + Fresh(fresh), + element.set(new HtmlPathElement( + tagNames.build(), + classNames.isEmpty() ? map() : map("class", String.join(" ", classNames.build())), + !fresh.get()))); + } + + Rule TagNames(ListVar tagNames) { + return Sequence( + Identifier(), + tagNames.append(match()), + ZeroOrMore(Sequence("|", Identifier(), tagNames.append(match())))); + } + + Rule ClassNames(ListVar classNames) { + Var className = new Var<>(); + return ZeroOrMore(Sequence(ClassName(className), classNames.append(className))); + } + + Rule ClassName(Var className) { + return Sequence(".", Identifier(), className.set(match())); + } + + Rule Fresh(Var fresh) { + return Sequence(fresh.set(false), Optional(":fresh", fresh.set(true))); + } + + Rule Identifier() { + return Sequence( + FirstOf(CharRange('a', 'z'), CharRange('A', 'Z')), + ZeroOrMore(FirstOf(CharRange('a', 'z'), CharRange('A', 'Z'), CharRange('0', '9'), Ch('-'), Ch('_')))); + } + + Rule Whitespace() { + return ZeroOrMore(AnyOf(" \t")); + } +} diff --git a/src/main/java/org/zwobble/mammoth/styles/parsing/ListVar.java b/src/main/java/org/zwobble/mammoth/styles/parsing/ListVar.java new file mode 100644 index 0000000..e23acf8 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/styles/parsing/ListVar.java @@ -0,0 +1,34 @@ +package org.zwobble.mammoth.styles.parsing; + + +import com.google.common.collect.ImmutableList; +import org.parboiled.support.Var; + +import java.util.List; + +import static org.zwobble.mammoth.util.MammothLists.list; + +class ListVar extends Var> { + boolean append(Var element) { + return append(element.get()); + } + + boolean append(T element) { + if (get() == null) { + set(ImmutableList.builder()); + } + return set(get().add(element)); + } + + public List build() { + if (get() == null) { + return list(); + } else { + return get().build(); + } + } + + public boolean isEmpty() { + return get() == null; + } +} diff --git a/src/main/java/org/zwobble/mammoth/styles/parsing/Parsing.java b/src/main/java/org/zwobble/mammoth/styles/parsing/Parsing.java new file mode 100644 index 0000000..761e7b8 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/styles/parsing/Parsing.java @@ -0,0 +1,23 @@ +package org.zwobble.mammoth.styles.parsing; + +import org.parboiled.BaseParser; +import org.parboiled.Parboiled; +import org.parboiled.Rule; +import org.parboiled.parserunners.ReportingParseRunner; +import org.parboiled.support.ParsingResult; + +import java.util.function.Function; + +public class Parsing { + public static > T parse(Class parserType, Function rule, String value) { + U parser = Parboiled.createParser(parserType); + ReportingParseRunner runner = new ReportingParseRunner<>(rule.apply(parser)); + ParsingResult result = runner.run(value); + if (result.hasErrors()) { + // TODO: wrap in result + throw new RuntimeException("Parse error"); + } else { + return result.valueStack.peek(); + } + } +} -- cgit v1.2.3