| OLD | NEW |
| 1 package parser | 1 package parser |
| 2 | 2 |
| 3 import ( | 3 import ( |
| 4 "fmt" | 4 "fmt" |
| 5 "math" | 5 "math" |
| 6 "mojom/mojom_parser/lexer" | 6 "mojom/mojom_parser/lexer" |
| 7 "mojom/mojom_parser/mojom" | 7 "mojom/mojom_parser/mojom" |
| 8 "strconv" | 8 "strconv" |
| 9 ) | 9 ) |
| 10 | 10 |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 attributes.List = append(attributes.List, mojom.MojomAttribute{k
ey, value}) | 310 attributes.List = append(attributes.List, mojom.MojomAttribute{k
ey, value}) |
| 311 | 311 |
| 312 nextToken = p.peekNextToken("I was reading an attributes section
.") | 312 nextToken = p.peekNextToken("I was reading an attributes section
.") |
| 313 if !p.OK() { | 313 if !p.OK() { |
| 314 return | 314 return |
| 315 } | 315 } |
| 316 p.consumeNextToken() | 316 p.consumeNextToken() |
| 317 if nextToken.Kind != lexer.RBracket && nextToken.Kind != lexer.C
omma { | 317 if nextToken.Kind != lexer.RBracket && nextToken.Kind != lexer.C
omma { |
| 318 switch nextToken.Kind { | 318 switch nextToken.Kind { |
| 319 case lexer.Module, lexer.Interface, lexer.Struct, lexer.
Union, lexer.Enum: | 319 case lexer.Module, lexer.Interface, lexer.Struct, lexer.
Union, lexer.Enum: |
| 320 » » » » message := fmt.Sprintf("The attribute section is
missing a closing ] before %s.", nextToken) | 320 » » » » message := fmt.Sprintf("Error: The attribute sec
tion is missing a closing ] before %s.", nextToken) |
| 321 p.parseErrorT(ParserErrorCodeUnexpectedToken, me
ssage, nextToken) | 321 p.parseErrorT(ParserErrorCodeUnexpectedToken, me
ssage, nextToken) |
| 322 return | 322 return |
| 323 default: | 323 default: |
| 324 p.unexpectedTokenError(nextToken, "comma or ]") | 324 p.unexpectedTokenError(nextToken, "comma or ]") |
| 325 return | 325 return |
| 326 } | 326 } |
| 327 } | 327 } |
| 328 } | 328 } |
| 329 | 329 |
| 330 return | 330 return |
| (...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 921 firstValue := true | 921 firstValue := true |
| 922 for attributes := p.parseAttributes(); !rbraceFound; attributes = p.pars
eAttributes() { | 922 for attributes := p.parseAttributes(); !rbraceFound; attributes = p.pars
eAttributes() { |
| 923 if !p.OK() { | 923 if !p.OK() { |
| 924 return false | 924 return false |
| 925 } | 925 } |
| 926 nextToken := p.peekNextToken("I was parsing an enum body.") | 926 nextToken := p.peekNextToken("I was parsing an enum body.") |
| 927 var duplicateNameError error = nil | 927 var duplicateNameError error = nil |
| 928 switch nextToken.Kind { | 928 switch nextToken.Kind { |
| 929 case lexer.Name: | 929 case lexer.Name: |
| 930 if !firstValue && !trailingCommaFound { | 930 if !firstValue && !trailingCommaFound { |
| 931 » » » » message := fmt.Sprintf("Expecting a comma after
%s before the next value %s.", | 931 » » » » message := fmt.Sprintf("Error: Expecting a comma
after %s before the next value %s.", |
| 932 p.lastConsumed, nextToken) | 932 p.lastConsumed, nextToken) |
| 933 p.parseErrorT(ParserErrorCodeUnexpectedToken, me
ssage, p.lastConsumed) | 933 p.parseErrorT(ParserErrorCodeUnexpectedToken, me
ssage, p.lastConsumed) |
| 934 return false | 934 return false |
| 935 } | 935 } |
| 936 firstValue = false | 936 firstValue = false |
| 937 name := p.readName() | 937 name := p.readName() |
| 938 p.attachToken() | 938 p.attachToken() |
| 939 nameToken := p.lastConsumed | 939 nameToken := p.lastConsumed |
| 940 var valueRef mojom.ValueRef | 940 var valueRef mojom.ValueRef |
| 941 if p.tryMatch(lexer.Equals) { | 941 if p.tryMatch(lexer.Equals) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1021 assigneeSpec := mojom.AssigneeSpec{ | 1021 assigneeSpec := mojom.AssigneeSpec{ |
| 1022 name, | 1022 name, |
| 1023 declaredType, | 1023 declaredType, |
| 1024 } | 1024 } |
| 1025 value := p.parseValue(assigneeSpec) | 1025 value := p.parseValue(assigneeSpec) |
| 1026 if !p.OK() { | 1026 if !p.OK() { |
| 1027 return | 1027 return |
| 1028 } | 1028 } |
| 1029 | 1029 |
| 1030 if !declaredType.MarkUsedAsConstantType() { | 1030 if !declaredType.MarkUsedAsConstantType() { |
| 1031 » » message := fmt.Sprintf("The type %s is not allowed as the type o
f a declared constant. "+ | 1031 » » message := fmt.Sprintf("Error: The type %s is not allowed as the
type of a declared constant. "+ |
| 1032 "Only simple types, strings and enum types may be the ty
pes of constants.", declaredType) | 1032 "Only simple types, strings and enum types may be the ty
pes of constants.", declaredType) |
| 1033 p.parseErrorT(ParserErrorCodeUnexpectedToken, message, declaredT
ypeToken) | 1033 p.parseErrorT(ParserErrorCodeUnexpectedToken, message, declaredT
ypeToken) |
| 1034 return | 1034 return |
| 1035 } | 1035 } |
| 1036 | 1036 |
| 1037 constant = mojom.NewUserDefinedConstant(p.DeclData(name, nameToken, attr
ibutes), declaredType, value) | 1037 constant = mojom.NewUserDefinedConstant(p.DeclData(name, nameToken, attr
ibutes), declaredType, value) |
| 1038 p.matchSemicolon() | 1038 p.matchSemicolon() |
| 1039 | 1039 |
| 1040 if !constant.ValidateValue() { | 1040 if !constant.ValidateValue() { |
| 1041 valueString := fmt.Sprintf("%v", value) | 1041 valueString := fmt.Sprintf("%v", value) |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1252 if p.tryMatch(lexer.LAngle) { | 1252 if p.tryMatch(lexer.LAngle) { |
| 1253 handleType := p.readText(lexer.Name) | 1253 handleType := p.readText(lexer.Name) |
| 1254 if !p.OK() { | 1254 if !p.OK() { |
| 1255 token := p.lastSeen | 1255 token := p.lastSeen |
| 1256 p.unexpectedTokenError(token, "a type of handle"
) | 1256 p.unexpectedTokenError(token, "a type of handle"
) |
| 1257 return nil | 1257 return nil |
| 1258 } | 1258 } |
| 1259 if p.match(lexer.RAngle) { | 1259 if p.match(lexer.RAngle) { |
| 1260 typeName = fmt.Sprintf("%s<%s>", typeName, handl
eType) | 1260 typeName = fmt.Sprintf("%s<%s>", typeName, handl
eType) |
| 1261 if builtInType = mojom.BuiltInType(typeName); bu
iltInType == nil { | 1261 if builtInType = mojom.BuiltInType(typeName); bu
iltInType == nil { |
| 1262 » » » » » message := fmt.Sprintf("Unrecognized typ
e of handle: %s.", typeName) | 1262 » » » » » message := fmt.Sprintf("Error: Unrecogni
zed type of handle: %s.", typeName) |
| 1263 p.parseErrorT(ParserErrorCodeUnexpectedT
oken, message, typeNameToken) | 1263 p.parseErrorT(ParserErrorCodeUnexpectedT
oken, message, typeNameToken) |
| 1264 return nil | 1264 return nil |
| 1265 } | 1265 } |
| 1266 } | 1266 } |
| 1267 } | 1267 } |
| 1268 if !p.OK() { | 1268 if !p.OK() { |
| 1269 return nil | 1269 return nil |
| 1270 } | 1270 } |
| 1271 } | 1271 } |
| 1272 | 1272 |
| 1273 // Check for nullable marker | 1273 // Check for nullable marker |
| 1274 if p.tryMatch(lexer.Qstn) { | 1274 if p.tryMatch(lexer.Qstn) { |
| 1275 if builtInType = mojom.BuiltInType(typeName + "?"); builtInType
== nil { | 1275 if builtInType = mojom.BuiltInType(typeName + "?"); builtInType
== nil { |
| 1276 » » » message := fmt.Sprintf("The type %s? is invalid because
the type %s may not be made nullable.", | 1276 » » » message := fmt.Sprintf("Error: The type %s? is invalid b
ecause the type %s may not be made nullable.", |
| 1277 typeName, typeName) | 1277 typeName, typeName) |
| 1278 p.parseErrorT(ParserErrorCodeUnexpectedToken, message, t
ypeNameToken) | 1278 p.parseErrorT(ParserErrorCodeUnexpectedToken, message, t
ypeNameToken) |
| 1279 return nil | 1279 return nil |
| 1280 } | 1280 } |
| 1281 } | 1281 } |
| 1282 | 1282 |
| 1283 return builtInType | 1283 return builtInType |
| 1284 } | 1284 } |
| 1285 | 1285 |
| 1286 // ARRAY_TYPE -> array langle TYPE [comma int_const_dec] rangle [qstn] | 1286 // ARRAY_TYPE -> array langle TYPE [comma int_const_dec] rangle [qstn] |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1340 keyToken := p.peekNextToken("Trying to read a type.") | 1340 keyToken := p.peekNextToken("Trying to read a type.") |
| 1341 keyType := p.parseType() | 1341 keyType := p.parseType() |
| 1342 p.match(lexer.Comma) | 1342 p.match(lexer.Comma) |
| 1343 valueType := p.parseType() | 1343 valueType := p.parseType() |
| 1344 if !p.match(lexer.RAngle) { | 1344 if !p.match(lexer.RAngle) { |
| 1345 return nil | 1345 return nil |
| 1346 } | 1346 } |
| 1347 nullable := p.tryMatch(lexer.Qstn) | 1347 nullable := p.tryMatch(lexer.Qstn) |
| 1348 | 1348 |
| 1349 if !keyType.MarkUsedAsMapKey() { | 1349 if !keyType.MarkUsedAsMapKey() { |
| 1350 » » message := fmt.Sprintf("The type %s is not allowed as the key ty
pe of a map. "+ | 1350 » » message := fmt.Sprintf("Error: The type %s is not allowed as the
key type of a map. "+ |
| 1351 "Only simple types, strings and enum types may be map ke
ys.", keyType) | 1351 "Only simple types, strings and enum types may be map ke
ys.", keyType) |
| 1352 p.parseErrorT(ParserErrorCodeUnexpectedToken, message, keyToken) | 1352 p.parseErrorT(ParserErrorCodeUnexpectedToken, message, keyToken) |
| 1353 return nil | 1353 return nil |
| 1354 } | 1354 } |
| 1355 | 1355 |
| 1356 return mojom.NewMapTypeRef(keyType, valueType, nullable) | 1356 return mojom.NewMapTypeRef(keyType, valueType, nullable) |
| 1357 } | 1357 } |
| 1358 | 1358 |
| 1359 // TYPE_REFERENCE -> INTERFACE_TYPE | STRUCT_TYPE | UNION_TYPE | ENUM_TYPE | 1359 // TYPE_REFERENCE -> INTERFACE_TYPE | STRUCT_TYPE | UNION_TYPE | ENUM_TYPE |
| 1360 // INTERFACE_TYPE -> IDENTIFIER [amp] [qstn] {{where IDENTIFIER resolves to an
interface}} | 1360 // INTERFACE_TYPE -> IDENTIFIER [amp] [qstn] {{where IDENTIFIER resolves to an
interface}} |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1450 p.consumeNextToken() | 1450 p.consumeNextToken() |
| 1451 intText := p.lastConsumed.Text | 1451 intText := p.lastConsumed.Text |
| 1452 | 1452 |
| 1453 // Set the base to 10 or 16. | 1453 // Set the base to 10 or 16. |
| 1454 base := 10 | 1454 base := 10 |
| 1455 switch nextToken.Kind { | 1455 switch nextToken.Kind { |
| 1456 case lexer.IntConstDec: | 1456 case lexer.IntConstDec: |
| 1457 break | 1457 break |
| 1458 case lexer.IntConstHex: | 1458 case lexer.IntConstHex: |
| 1459 if !acceptHex { | 1459 if !acceptHex { |
| 1460 » » » message := fmt.Sprintf("Illegal value %s. Only a decimal
integer literal is allowed here. "+ | 1460 » » » message := fmt.Sprintf("Illegal value: %s. Only a decima
l integer literal is allowed here. "+ |
| 1461 "Hexadecimal is not valid.", nextToken) | 1461 "Hexadecimal is not valid.", nextToken) |
| 1462 p.parseErrorT(ParserErrorCodeUnexpectedToken, message, n
extToken) | 1462 p.parseErrorT(ParserErrorCodeUnexpectedToken, message, n
extToken) |
| 1463 return | 1463 return |
| 1464 } | 1464 } |
| 1465 if len(intText) < 3 { | 1465 if len(intText) < 3 { |
| 1466 » » » message := fmt.Sprintf("Invalid hex integer literal %q."
, intText) | 1466 » » » message := fmt.Sprintf("Invalid hex integer literal: %q.
", intText) |
| 1467 p.parseErrorT(ParserErrorCodeIntegerParseError, message,
nextToken) | 1467 p.parseErrorT(ParserErrorCodeIntegerParseError, message,
nextToken) |
| 1468 return | 1468 return |
| 1469 } | 1469 } |
| 1470 intText = intText[2:] | 1470 intText = intText[2:] |
| 1471 base = 16 | 1471 base = 16 |
| 1472 | 1472 |
| 1473 default: | 1473 default: |
| 1474 p.unexpectedTokenError(nextToken, "a positive integer literal") | 1474 p.unexpectedTokenError(nextToken, "a positive integer literal") |
| 1475 return | 1475 return |
| 1476 } | 1476 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1579 return true | 1579 return true |
| 1580 } | 1580 } |
| 1581 | 1581 |
| 1582 func (p *Parser) matchSemicolonToken(previousToken lexer.Token) bool { | 1582 func (p *Parser) matchSemicolonToken(previousToken lexer.Token) bool { |
| 1583 if !p.OK() { | 1583 if !p.OK() { |
| 1584 return false | 1584 return false |
| 1585 } | 1585 } |
| 1586 if p.match(lexer.Semi) { | 1586 if p.match(lexer.Semi) { |
| 1587 return true | 1587 return true |
| 1588 } | 1588 } |
| 1589 » message := fmt.Sprintf("Missing semicolon after %s.", previousToken) | 1589 » message := fmt.Sprintf("Error: Missing semicolon after %s.", previousTok
en) |
| 1590 p.parseErrorT(ParserErrorCodeUnexpectedToken, message, previousToken) | 1590 p.parseErrorT(ParserErrorCodeUnexpectedToken, message, previousToken) |
| 1591 return false | 1591 return false |
| 1592 } | 1592 } |
| 1593 | 1593 |
| 1594 func (p *Parser) matchSemicolon() bool { | 1594 func (p *Parser) matchSemicolon() bool { |
| 1595 return p.matchSemicolonToken(p.lastConsumed) | 1595 return p.matchSemicolonToken(p.lastConsumed) |
| 1596 } | 1596 } |
| 1597 | 1597 |
| 1598 func (p *Parser) readText(kind lexer.TokenKind) (text string) { | 1598 func (p *Parser) readText(kind lexer.TokenKind) (text string) { |
| 1599 if !p.OK() { | 1599 if !p.OK() { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1635 func (p *Parser) readOrdinal() (ordinalValue int64, err error) { | 1635 func (p *Parser) readOrdinal() (ordinalValue int64, err error) { |
| 1636 ordinalValue = -1 | 1636 ordinalValue = -1 |
| 1637 if !p.OK() { | 1637 if !p.OK() { |
| 1638 return | 1638 return |
| 1639 } | 1639 } |
| 1640 | 1640 |
| 1641 if p.tryMatch(lexer.Ordinal) { | 1641 if p.tryMatch(lexer.Ordinal) { |
| 1642 intTextToParse := p.lastConsumed.Text[1:] | 1642 intTextToParse := p.lastConsumed.Text[1:] |
| 1643 ordinalValue, err = strconv.ParseInt(intTextToParse, 10, 64) | 1643 ordinalValue, err = strconv.ParseInt(intTextToParse, 10, 64) |
| 1644 if err != nil || ordinalValue < 0 || ordinalValue >= math.MaxUin
t32 { | 1644 if err != nil || ordinalValue < 0 || ordinalValue >= math.MaxUin
t32 { |
| 1645 » » » err = fmt.Errorf("Invalid ordinal string following `@`:
%q. Ordinals must be decimal integers between 0 and %d.", | 1645 » » » err = fmt.Errorf("Error: Invalid ordinal string followin
g '@': %q. Ordinals must be decimal integers between 0 and %d.", |
| 1646 intTextToParse, math.MaxUint32-1) | 1646 intTextToParse, math.MaxUint32-1) |
| 1647 return | 1647 return |
| 1648 } | 1648 } |
| 1649 } | 1649 } |
| 1650 return | 1650 return |
| 1651 } | 1651 } |
| 1652 | 1652 |
| 1653 func (p *Parser) DeclData(name string, nameToken lexer.Token, attributes *mojom.
Attributes) mojom.DeclarationData { | 1653 func (p *Parser) DeclData(name string, nameToken lexer.Token, attributes *mojom.
Attributes) mojom.DeclarationData { |
| 1654 return mojom.DeclData(name, p.mojomFile, nameToken, attributes) | 1654 return mojom.DeclData(name, p.mojomFile, nameToken, attributes) |
| 1655 } | 1655 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1687 // unexpectedTokenError() sets the parser's current error to a ParseError | 1687 // unexpectedTokenError() sets the parser's current error to a ParseError |
| 1688 // with error code |ParserErrorCodeUnexpectedToken| and an error message | 1688 // with error code |ParserErrorCodeUnexpectedToken| and an error message |
| 1689 // of the form: | 1689 // of the form: |
| 1690 // | 1690 // |
| 1691 // Unexpected '}'. Expecting a semicolon. | 1691 // Unexpected '}'. Expecting a semicolon. |
| 1692 // | 1692 // |
| 1693 // |expected| should be a noun-phrase such as "a semicolon". | 1693 // |expected| should be a noun-phrase such as "a semicolon". |
| 1694 func (p *Parser) unexpectedTokenError(token lexer.Token, expected string) { | 1694 func (p *Parser) unexpectedTokenError(token lexer.Token, expected string) { |
| 1695 var message string | 1695 var message string |
| 1696 switch token.Kind { | 1696 switch token.Kind { |
| 1697 » case lexer.ErrorUnknown, lexer.ErrorIllegalChar, | 1697 » case lexer.ErrorUnterminatedStringLiteral, lexer.ErrorUnterminatedCommen
t: |
| 1698 » » lexer.ErrorUnterminatedStringLiteral, | 1698 » » message = fmt.Sprintf("Error: %s", token) |
| 1699 » » lexer.ErrorUnterminatedComment: | |
| 1700 » » message = fmt.Sprintf("%s. Expecting %s.", token, expected) | |
| 1701 default: | 1699 default: |
| 1702 » » message = fmt.Sprintf("Unexpected %s. Expecting %s.", token, exp
ected) | 1700 » » message = fmt.Sprintf("Error: Unexpected %s. Expecting %s.", tok
en, expected) |
| 1703 } | 1701 } |
| 1704 p.parseErrorT(ParserErrorCodeUnexpectedToken, message, token) | 1702 p.parseErrorT(ParserErrorCodeUnexpectedToken, message, token) |
| 1705 } | 1703 } |
| OLD | NEW |