| 397 | } |
| 398 | |
| 399 | Field parseField(bool allowDirection) { |
| 400 | Field field; |
| 401 | field.line = token_.line; |
| 402 | if (token_.kind == Tok::Ident && (token_.text == "in" || token_.text == "out")) { |
| 403 | if (!allowDirection) fail("direction marker is not allowed here"); |
| 404 | field.dir = token_.text == "out" ? Dir::Out : Dir::In; |
| 405 | advance(); |
| 406 | } |
| 407 | field.type = expect(Tok::Ident, "field type").text; |
| 408 | field.name = expect(Tok::Ident, "field name").text; |
| 409 | if (token_.kind == Tok::LBrack) { |
| 410 | advance(); |
| 411 | field.lenRef = expect(Tok::Ident, "byte length field").text; |
| 412 | expect(Tok::RBrack); |
| 413 | } |
| 414 | if (field.type == "bytes" && field.lenRef.empty()) |
| 415 | fail(field.line, "bytes field '" + field.name + "' requires a length field"); |
| 416 | if (field.type != "bytes" && !field.lenRef.empty()) |
| 417 | fail(field.line, "only bytes fields may declare a length field"); |
| 418 | return field; |
| 419 | } |
| 420 | |
| 421 | std::string parseScopedName() { |
| 422 | std::string result = expect(Tok::Ident, "identifier").text; |