From 1e9983e9011ebfd35b301e1c3efd280894ac5352 Mon Sep 17 00:00:00 2001 From: walterxie Date: Wed, 29 Nov 2023 13:06:13 +1300 Subject: [PATCH] Implement singleton class MacroProcessor #420 --- .../java/lphy/core/io/MacroProcessor.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 lphy/src/main/java/lphy/core/io/MacroProcessor.java diff --git a/lphy/src/main/java/lphy/core/io/MacroProcessor.java b/lphy/src/main/java/lphy/core/io/MacroProcessor.java new file mode 100644 index 00000000..dee6d4f8 --- /dev/null +++ b/lphy/src/main/java/lphy/core/io/MacroProcessor.java @@ -0,0 +1,82 @@ +package lphy.core.io; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Inspired by templating languages e.g. Mustache. + * Only support {{identifier = default_value}} + */ +public class MacroProcessor { + + // {{n = 10}} + public static final String CONST_MACRO = "\\{\\{\\s*(\\w+)\\s*=\\s*(.*?)\\s*\\}\\}"; + private final Pattern pattern; + + public MacroProcessor(String regex) { + this.pattern = Pattern.compile(regex); + } + + public MacroProcessor() { + this(CONST_MACRO); + } + + // Singleton + private static MacroProcessor INSTANCE; + public static MacroProcessor getInstance() { + if(INSTANCE == null) { + INSTANCE = new MacroProcessor(); + } + return INSTANCE; + } + + public static String process(String input) { + Map macroMap = getInstance().getMacroMap(input); + // TODO modify the macroMap based on user input? + return getInstance().getResult(input, macroMap); + } + + public Map getMacroMap(String input) { + Map macroMap = new HashMap<>(); + + // Populate the macroMap based on the initial matches + Matcher matcher = pattern.matcher(input); + + while (matcher.find()) { + String identifier = matcher.group(1); + String literal = matcher.group(2); + macroMap.put(identifier, literal); + } + return macroMap; + } + + public String getResult(String input, Map macroMap) { + Matcher replaceMatcher = pattern.matcher(input); + StringBuilder stringBuffer = new StringBuilder(); + + while (replaceMatcher.find()) { + String replacement = macroMap.get(replaceMatcher.group(1)); + if (replacement != null) { + // The String produced will match the sequence of characters in s treated as a literal sequence. + // Slashes ('\') and dollar signs ('$') will be given no special meaning. + replacement = Matcher.quoteReplacement(replacement); + replaceMatcher.appendReplacement(stringBuffer, replacement); + } + } + replaceMatcher.appendTail(stringBuffer); + // Result contains the modified string + return stringBuffer.toString(); + } + + public static void main(String[] args) { + String input = "{{identifier1 = value1}} some text {{identifier2 = value2}}"; + + String result = MacroProcessor.process(input); + + System.out.println(result); + } + +} +