Skip to content

Commit f00a0d3

Browse files
committed
try refactoring monomial parser somewhat
1 parent ea96bf4 commit f00a0d3

File tree

2 files changed

+65
-50
lines changed

2 files changed

+65
-50
lines changed

mlir/lib/Dialect/Polynomial/IR/PolynomialAttributes.cpp

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,39 @@ void PolynomialAttr::print(AsmPrinter &p) const {
2626

2727
/// Try to parse a monomial. If successful, populate the fields of the outparam
2828
/// `monomial` with the results, and the `variable` outparam with the parsed
29-
/// variable name.
29+
/// variable name. Sets shouldParseMore to true if the monomial is followed by
30+
/// a '+'.
3031
ParseResult parseMonomial(AsmParser &parser, Monomial &monomial,
31-
llvm::StringRef &variable, bool *isConstantTerm) {
32+
llvm::StringRef &variable, bool *isConstantTerm,
33+
bool *shouldParseMore) {
3234
APInt parsedCoeff(apintBitWidth, 1);
33-
auto result = parser.parseOptionalInteger(parsedCoeff);
34-
35-
// Variable name
36-
result = parser.parseOptionalKeyword(&variable);
37-
if (!result.has_value() || failed(*result)) {
38-
// We allow "failed" because it triggers when the next token is a +,
39-
// which is allowed when the input is the constant term.
40-
monomial.coefficient = parsedCoeff;
35+
auto parsedCoeffResult = parser.parseOptionalInteger(parsedCoeff);
36+
monomial.coefficient = parsedCoeff;
37+
38+
*isConstantTerm = false;
39+
*shouldParseMore = false;
40+
41+
// A + indicates it's a constant term with more to go, as in `1 + x`.
42+
if (succeeded(parser.parseOptionalPlus())) {
43+
// If no coefficient was parsed, and there's a +, then it's effectively
44+
// parsing an empty string.
45+
if (!parsedCoeffResult.has_value()) {
46+
return failure();
47+
}
48+
monomial.exponent = APInt(apintBitWidth, 0);
49+
*isConstantTerm = true;
50+
*shouldParseMore = true;
51+
return success();
52+
}
53+
54+
// A monomial can be a trailing constant term, as in `x + 1`
55+
if (failed(parser.parseOptionalKeyword(&variable))) {
56+
// If neither a coefficient nor a variable was found, then it's effectively
57+
// parsing an empty string.
58+
if (!parsedCoeffResult.has_value()) {
59+
return failure();
60+
}
61+
4162
monomial.exponent = APInt(apintBitWidth, 0);
4263
*isConstantTerm = true;
4364
return success();
@@ -46,29 +67,30 @@ ParseResult parseMonomial(AsmParser &parser, Monomial &monomial,
4667
// Parse exponentiation symbol as **
4768
// We can't use caret because it's reserved for basic block identifiers
4869
// If no star is present, it's treated as a polynomial with exponent 1
49-
if (failed(parser.parseOptionalStar())) {
50-
monomial.coefficient = parsedCoeff;
51-
monomial.exponent = APInt(apintBitWidth, 1);
52-
return success();
53-
}
70+
if (succeeded(parser.parseOptionalStar())) {
71+
// If there's one * there must be two
72+
if (failed(parser.parseStar())) {
73+
parser.emitError(parser.getCurrentLocation(),
74+
"exponents must be specified as a double-asterisk `**`");
75+
return failure();
76+
}
5477

55-
// If there's one * there must be two
56-
if (failed(parser.parseStar())) {
57-
parser.emitError(parser.getCurrentLocation(),
58-
"exponents must be specified as a double-asterisk `**`");
59-
return failure();
60-
}
78+
// If there's a **, then the integer exponent is required.
79+
APInt parsedExponent(apintBitWidth, 0);
80+
if (failed(parser.parseInteger(parsedExponent))) {
81+
parser.emitError(parser.getCurrentLocation(),
82+
"found invalid integer exponent");
83+
return failure();
84+
}
6185

62-
// If there's a **, then the integer exponent is required.
63-
APInt parsedExponent(apintBitWidth, 0);
64-
if (failed(parser.parseInteger(parsedExponent))) {
65-
parser.emitError(parser.getCurrentLocation(),
66-
"found invalid integer exponent");
67-
return failure();
86+
monomial.exponent = parsedExponent;
87+
} else {
88+
monomial.exponent = APInt(apintBitWidth, 1);
6889
}
6990

70-
monomial.coefficient = parsedCoeff;
71-
monomial.exponent = parsedExponent;
91+
if (succeeded(parser.parseOptionalPlus())) {
92+
*shouldParseMore = true;
93+
}
7294
return success();
7395
}
7496

@@ -83,9 +105,11 @@ Attribute PolynomialAttr::parse(AsmParser &parser, Type type) {
83105
while (true) {
84106
Monomial parsedMonomial;
85107
llvm::StringRef parsedVariableRef;
86-
bool isConstantTerm = false;
108+
bool isConstantTerm;
109+
bool shouldParseMore;
87110
if (failed(parseMonomial(parser, parsedMonomial, parsedVariableRef,
88-
&isConstantTerm))) {
111+
&isConstantTerm, &shouldParseMore))) {
112+
parser.emitError(parser.getCurrentLocation(), "expected a monomial");
89113
return {};
90114
}
91115

@@ -105,26 +129,16 @@ Attribute PolynomialAttr::parse(AsmParser &parser, Type type) {
105129
}
106130
exponents.insert(parsedMonomial.exponent);
107131

108-
// Parse optional +. If a + is absent, require > and break, otherwise forbid
109-
// > and continue with the next monomial.
110-
// ParseOptional{Plus, Greater} does not return an OptionalParseResult, so
111-
// failed means that the token was not found.
112-
if (failed(parser.parseOptionalPlus())) {
113-
if (succeeded(parser.parseGreater())) {
114-
break;
115-
}
116-
parser.emitError(
117-
parser.getCurrentLocation(),
118-
"expected + and more monomials, or > to end polynomial attribute");
119-
return {};
120-
}
132+
if (shouldParseMore)
133+
continue;
121134

122135
if (succeeded(parser.parseOptionalGreater())) {
123-
parser.emitError(
124-
parser.getCurrentLocation(),
125-
"expected another monomial after +, but found > ending attribute");
126-
return {};
136+
break;
127137
}
138+
parser.emitError(
139+
parser.getCurrentLocation(),
140+
"expected + and more monomials, or > to end polynomial attribute");
141+
return {};
128142
}
129143

130144
if (variables.size() > 1) {

mlir/test/Dialect/Polynomial/attributes.mlir

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// -----
88

99
// expected-error@below {{expected integer value}}
10+
// expected-error@below {{expected a monomial}}
1011
// expected-error@below {{found invalid integer exponent}}
1112
#my_poly = #polynomial.polynomial<5 + x**f>
1213
#ring1 = #polynomial.ring<coefficientType=i32, coefficientModulus=2837465, polynomialModulus=#my_poly>
@@ -19,17 +20,17 @@
1920

2021
// -----
2122

22-
// expected-error@below {{expected '>'}}
2323
// expected-error@below {{expected + and more monomials, or > to end polynomial attribute}}
2424
#my_poly = #polynomial.polynomial<5 + x**2 7>
2525
#ring1 = #polynomial.ring<coefficientType=i32, coefficientModulus=2837465, polynomialModulus=#my_poly>
2626

2727
// -----
2828

29+
// expected-error@below {{expected a monomial}}
2930
#my_poly = #polynomial.polynomial<5 + x**2 +>
30-
// expected-error@below {{expected another monomial after +, but found > ending attribute}}
3131
#ring1 = #polynomial.ring<coefficientType=i32, coefficientModulus=2837465, polynomialModulus=#my_poly>
3232

33+
3334
// -----
3435

3536
#my_poly = #polynomial.polynomial<5 + x**2>

0 commit comments

Comments
 (0)