xref: /aosp_15_r20/external/cldr/tools/cldr-code/src/main/java/org/unicode/cldr/util/RegexFileParser.java (revision 912701f9769bb47905792267661f0baf2b85bed5)
1 package org.unicode.cldr.util;
2 
3 import java.io.BufferedReader;
4 import org.unicode.cldr.util.CldrUtility.VariableReplacer;
5 
6 /**
7  * Parses a file of regexes for use in RegexLookup or any other class that requires a list of
8  * regexes.
9  *
10  * @author jchye
11  */
12 public class RegexFileParser {
13     private RegexLineParser lineParser;
14     private VariableProcessor varProcessor = DEFAULT_VARIABLE_PROCESSOR;
15 
16     /** Parses a line given to it by the RegexFileParser. */
17     public interface RegexLineParser {
parse(String line)18         public void parse(String line);
19     }
20 
21     /** Stores variables given to it by the RegexFileParser and performs replacements if needed. */
22     public interface VariableProcessor {
add(String variable, String variableName)23         public void add(String variable, String variableName);
24 
replace(String str)25         public String replace(String str);
26     }
27 
28     private static final VariableProcessor DEFAULT_VARIABLE_PROCESSOR =
29             new VariableProcessor() {
30                 VariableReplacer variables = new VariableReplacer();
31 
32                 @Override
33                 public void add(String variableName, String value) {
34                     variables.add(variableName, value);
35                 }
36 
37                 @Override
38                 public String replace(String str) {
39                     return variables.replace(str);
40                 }
41             };
42 
setLineParser(RegexLineParser lineParser)43     public void setLineParser(RegexLineParser lineParser) {
44         this.lineParser = lineParser;
45     }
46 
setVariableProcessor(VariableProcessor varProcessor)47     public void setVariableProcessor(VariableProcessor varProcessor) {
48         this.varProcessor = varProcessor;
49     }
50 
51     /**
52      * Parses the specified text file.
53      *
54      * @param a class relative to filename
55      * @param filename the name of the text file to be parsed
56      */
parse(Class<?> baseClass, String filename)57     public void parse(Class<?> baseClass, String filename) {
58         BufferedReader reader = FileReaders.openFile(baseClass, filename);
59         Iterable<String> rlsi = With.toIterable(new FileReaders.ReadLineSimpleIterator(reader));
60         parseStrings(filename, rlsi);
61     }
62 
63     /**
64      * Parses the specified lines, as if they came from a text file.
65      *
66      * @param a class relative to filename
67      * @param filename the name of the text file to be parsed
68      */
parseStrings(String source, Iterable<String> rlsi)69     public void parseStrings(String source, Iterable<String> rlsi) {
70         String line = null;
71         int lineNumber = 0;
72         try {
73             for (String lineItem : rlsi) {
74                 line = lineItem; // copy for possible exception
75                 lineNumber++;
76                 line = line.trim();
77                 // Skip comments.
78                 if (line.length() == 0 || line.startsWith("#")) continue;
79                 // Read variables.
80                 if (line.charAt(0) == '%') {
81                     int pos = line.indexOf("=");
82                     if (pos < 0) {
83                         throw new IllegalArgumentException(
84                                 "Failed to read variable in "
85                                         + source
86                                         + "\t\t("
87                                         + lineNumber
88                                         + ") "
89                                         + line);
90                     }
91                     String varName = line.substring(0, pos).trim();
92                     String varValue = line.substring(pos + 1).trim();
93                     varProcessor.add(varName, varValue);
94                     continue;
95                 }
96                 if (line.contains("%")) {
97                     line = varProcessor.replace(line);
98                 }
99                 // Process a line in the input file for xpath conversion.
100                 lineParser.parse(line);
101             }
102         } catch (Exception e) {
103             throw new IllegalArgumentException(
104                     "Error reading " + source + " at line " + lineNumber + ": " + line, e);
105         }
106     }
107 }
108