# parserc-java **Repository Path**: winie/parserc-java ## Basic Information - **Project Name**: parserc-java - **Description**: java开发的解析器组合子(Parser Combinator)库 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2022-08-02 - **Last Updated**: 2022-11-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # parserc-java parserc-java是用java实现的解析器组合子(Parser Combinator)库,可以方便地以自底向上的方式构建复杂的解析器。 ## 计算器示例 ```java public class ExprCalc { private static final Parser w = chs(' ', '\t', '\r', '\n'); private static final Parser ws = w.many(); private static final Parser digit = range('0', '9'); private static final Parser add = ch('+').surround(ws); private static final Parser sub = ch('-').surround(ws); private static final Parser mul = ch('*').surround(ws); private static final Parser div = ch('/').surround(ws); private static final Parser lp = ch('(').surround(ws); private static final Parser rp = ch(')').surround(ws); private static final Parser digits = digit.many1().map(ExprCalc::join); private static final Parser integer = digits.map(Double::parseDouble); private static final Parser decimal = seq(digits, ch('.'), digits).map(ExprCalc::join).map(Double::parseDouble); private static final Parser number = decimal.or(integer).surround(ws); private static final Parser bracketExpr = skip(lp).and(lazy(ExprCalc::getExpr)).skip(rp); private static final Parser negExpr = skip(sub).and(lazy(ExprCalc::getFact)).map(e -> -e); private static final Parser fact = oneOf(number, bracketExpr, negExpr); private static final Parser term = fact.and(mul.or(div).and(fact).many()).map(ExprCalc::calc); private static final Parser expr = term.and(add.or(sub).and(term).many()).map(ExprCalc::calc); private static Parser getFact() { return fact; } private static Parser getExpr() { return expr; } private static String join(List list) { return list.stream().map(Objects::toString).collect(Collectors.joining()); } private static Double calc(Pair>> p) { double res = p.getFirst(); for (Pair pp : p.getSecond()) { switch (pp.getFirst()) { case '+': res += pp.getSecond(); break; case '-': res -= pp.getSecond(); break; case '*': res *= pp.getSecond(); break; case '/': res /= pp.getSecond(); break; } } return res; } public static Double eval(String input) { return expr.parse(input); } } public class Main { public static void main(String[] args) { System.out.println(ExprCalc.eval("77.58 * (6 / 3.14 + 55.2234) - 2 * 6.1 / (1.0 + 2 / (4.0 - 3.8 * 5))")); } } ``` ## JSON示例 ```java public class JsonParser { private static final Parser w = chs(' ', '\t', '\n', '\r'); private static final Parser> ws = w.many(); private static final Parser digit = range('0', '9').map(Objects::toString); private static final Parser digits = digit.many1().map(JsonParser::join); private static final Parser integer = digits.map(Integer::parseInt).surround(ws); private static final Parser decimal = seq(digits, ch('.'), digits).map(JsonParser::join).map(Double::parseDouble); private static final Parser string = skip(ch('"')).and(not('"').many()).skip(ch('"')).map(JsonParser::join); private static final Parser bool = strs("true", "false").map(Boolean::parseBoolean).surround(ws); private static final Parser objStart = ch('{').surround(ws); private static final Parser objEnd = ch('}').surround(ws); private static final Parser arrStart = ch('[').surround(ws); private static final Parser arrEnd = ch(']').surround(ws); private static final Parser colon = ch(':').surround(ws); private static final Parser comma = ch(',').surround(ws); private static final Parser lazyJsonObj = lazy(JsonParser::getJsonObj); private static final Parser> arr = skip(arrStart).and(separate(comma, lazyJsonObj).opt(Collections.emptyList())).skip(arrEnd); private static final Parser> pair = string.skip(colon).and(lazyJsonObj); private static final Parser> obj = skip(objStart).and(separate(comma, pair).opt(Collections.emptyList())).skip(objEnd) .map(ps -> ps.stream().collect(Collectors.toMap(Pair::getFirst, Pair::getSecond))); private static final Parser jsonObj = oneOf( decimal.mapTo(Object.class), integer.mapTo(Object.class), string.mapTo(Object.class), bool.mapTo(Object.class), arr.mapTo(Object.class), obj.mapTo(Object.class) ); private static Parser getJsonObj() { return jsonObj; } private static String join(List list) { return list.stream().map(Objects::toString).collect(Collectors.joining("")); } public static Object parse(String input) throws ParseException { return jsonObj.parse(input); } } ```