Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: mojom/mojom_parser/parser/parsing.go

Issue 1506023005: New Mojom parser: Fix up error messages for lexing errors. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Adds new sha1. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojom/mojom_parser/parser/parser_test.go ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « mojom/mojom_parser/parser/parser_test.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698