package org.softlang.company.features.parser;
import static org.softlang.company.features.parser.CompanyLexer.*;
import static parseLib.acceptor.Acceptor.*;
import parseLib.parser.*;
import parseLib.util.*;
import javaf.prelude.Function1;
import java.util.List;
/**
* A combinator-based parser for companies.
* All salaries are totaled.
*/
public class CompanyParser extends Parser<Double> {
/**
* Parse companies.
*/
public static Parser<Double> company() {
return new Parser<Double>() {
public Double parse(Input i) {
return (
mkSnd(
sequence(
SPECIAL("company"),
STRING,
SPECIAL("{")),
mkFst(
mkFunction(
mkStar(department()),
sumList
),
sequence(
SPECIAL("}"),
EOF // Test that all input has been consumed.
)))).parse(i);
}
};
}
/**
* Parse departments.
*/
public static Parser<Double> department() {
return new Parser<Double>() {
public Double parse(Input i) {
return (
mkFunction(
mkTuple3(
mkSnd(
sequence(
SPECIAL("department"),
STRING,
SPECIAL("{")),
employee("manager")),
mkStar(employee("employee")),
mkFst(
mkStar(department()),
SPECIAL("}"))),
new Function1<Tuple3<Double,List<Double>,List<Double>>,Double>() {
public Double apply(Tuple3<Double, List<Double>, List<Double>> t) {
return sumTriplet.apply(t);
}
}
)).parse(i);
}
};
}
/**
* Parse employees.
*/
public static Parser<Double> employee(final String keyword) {
return new Parser<Double>() {
public Double parse(Input i) {
return (
mkSnd(
sequence(
SPECIAL(keyword),
STRING,
SPECIAL("{"),
SPECIAL("address"),
STRING,
SPECIAL("salary")),
mkFst(
new MkDouble(FLOAT),
SPECIAL("}")
))).parse(i);
}
};
}
/**
* Invoke start symbol.
*/
public Double parse(Input i) {
return company().parse(i);
}
// Sum up elements in a list
private static Function1<List<Double>,Double> sumList =
new Function1<List<Double>,Double>() {
public Double apply(List<Double> l) {
Double result = 0.0;
for (Double d : l) result += d;
return result;
}
};
// Sum up elements in a triplet
private static Function1<Tuple3<Double,List<Double>,List<Double>>,Double> sumTriplet =
new Function1<Tuple3<Double,List<Double>,List<Double>>,Double>() {
public Double apply(Tuple3<Double,List<Double>,List<Double>> t) {
Double result = 0.0;
result += t.proj1;
for (Double d : t.proj2) result += d;
for (Double d : t.proj3) result += d;
return result;
}
};
}