@@ -26,18 +26,39 @@ void PolynomialAttr::print(AsmPrinter &p) const {
26
26
27
27
// / Try to parse a monomial. If successful, populate the fields of the outparam
28
28
// / `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 '+'.
30
31
ParseResult parseMonomial (AsmParser &parser, Monomial &monomial,
31
- llvm::StringRef &variable, bool *isConstantTerm) {
32
+ llvm::StringRef &variable, bool *isConstantTerm,
33
+ bool *shouldParseMore) {
32
34
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
+
41
62
monomial.exponent = APInt (apintBitWidth, 0 );
42
63
*isConstantTerm = true ;
43
64
return success ();
@@ -46,29 +67,30 @@ ParseResult parseMonomial(AsmParser &parser, Monomial &monomial,
46
67
// Parse exponentiation symbol as **
47
68
// We can't use caret because it's reserved for basic block identifiers
48
69
// 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
+ }
54
77
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
+ }
61
85
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 );
68
89
}
69
90
70
- monomial.coefficient = parsedCoeff;
71
- monomial.exponent = parsedExponent;
91
+ if (succeeded (parser.parseOptionalPlus ())) {
92
+ *shouldParseMore = true ;
93
+ }
72
94
return success ();
73
95
}
74
96
@@ -83,9 +105,11 @@ Attribute PolynomialAttr::parse(AsmParser &parser, Type type) {
83
105
while (true ) {
84
106
Monomial parsedMonomial;
85
107
llvm::StringRef parsedVariableRef;
86
- bool isConstantTerm = false ;
108
+ bool isConstantTerm;
109
+ bool shouldParseMore;
87
110
if (failed (parseMonomial (parser, parsedMonomial, parsedVariableRef,
88
- &isConstantTerm))) {
111
+ &isConstantTerm, &shouldParseMore))) {
112
+ parser.emitError (parser.getCurrentLocation (), " expected a monomial" );
89
113
return {};
90
114
}
91
115
@@ -105,26 +129,16 @@ Attribute PolynomialAttr::parse(AsmParser &parser, Type type) {
105
129
}
106
130
exponents.insert (parsedMonomial.exponent );
107
131
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 ;
121
134
122
135
if (succeeded (parser.parseOptionalGreater ())) {
123
- parser.emitError (
124
- parser.getCurrentLocation (),
125
- " expected another monomial after +, but found > ending attribute" );
126
- return {};
136
+ break ;
127
137
}
138
+ parser.emitError (
139
+ parser.getCurrentLocation (),
140
+ " expected + and more monomials, or > to end polynomial attribute" );
141
+ return {};
128
142
}
129
143
130
144
if (variables.size () > 1 ) {
0 commit comments