Last active
July 20, 2018 01:30
-
-
Save huytd/9788d069db85ea024f35daba58019a0a to your computer and use it in GitHub Desktop.
Hex color parsing using parser combinator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const match_char = (c: string) => (input: string) => { | |
if (input[0] === c) { | |
return {success: true, value: input[0], rest: input.slice(1), error: null} | |
} | |
return {success: false, value: null, rest: input, error: new Error("Expected " + c + " but found " + input[0] + "\nRemaining: " + input )} | |
}; | |
const any_char = (input: string) => { | |
if (typeof input[0] === 'string') { | |
return {success: true, value: input[0], rest: input.slice(1), error: null} | |
} | |
return {success: false, value: null, rest: input, error: new Error("Expected a character, found not a char\nRemaining: " + input )} | |
}; | |
const combine = (parsers: Array<any>) => (input: string) => { | |
let next = input; | |
let result = []; | |
for (let i = 0; i < parsers.length; i++) { | |
const parser: any = parsers[i]; | |
const { success, value, rest, error } = parser(next); | |
if (!success) { | |
return { success, value, rest, error }; | |
} else { | |
result.push(value); | |
} | |
next = rest; | |
} | |
return { success: true, value: result, rest: next, error: null }; | |
}; | |
const hex_primitive = (s: string) => { | |
let {success, value, rest, error} = combine([ any_char, any_char ])(s); | |
if (success) { | |
return { success, value: value.join(""), rest, error }; | |
} else { | |
return { success, value, rest, error }; | |
} | |
} | |
const hex_color = (s: string) => { | |
let {success, value, rest, error} = combine([ match_char('#'), hex_primitive, hex_primitive, hex_primitive ])(s); | |
if (success) { | |
let colors = value.slice(1).map(hex => parseInt(hex, 16)); | |
return colors; | |
} else { | |
throw error; | |
} | |
}; | |
hex_color("#5A4B3C"); // Should success | |
hex_color("5A4B3C"); // Expected '#' found '5' | |
hex_color("#5AB3C"); // Expected a character, found not a character |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const match_char = (c: string) => (input: string) => { | |
if (input[0] === c) { | |
return {success: true, value: input[0], rest: input.slice(1)} | |
} | |
return {success: false, value: null, rest: input} | |
}; | |
const any_char = (input: string) => { | |
if (typeof input[0] === 'string') { | |
return {success: true, value: input[0], rest: input.slice(1)} | |
} | |
return {success: false, value: null, rest: input} | |
}; | |
const combine = (parsers: Array<any>) => (input: string) => { | |
let next = input; | |
let result = []; | |
for (let i = 0; i < parsers.length; i++) { | |
const parser: any = parsers[i]; | |
const { success, value, rest } = parser(next); | |
if (!success) { | |
return { success, value, rest }; | |
} else { | |
result.push(value); | |
} | |
next = rest; | |
} | |
return { success: true, value: result, rest: next }; | |
}; | |
const hex_primitive = (s: string) => { | |
let {success, value, rest} = combine([ any_char, any_char ])(s); | |
return { success: success, value: value.join(""), rest: rest }; | |
} | |
const hex_color = (s: string) => { | |
let {success, value, rest} = combine([ match_char('#'), hex_primitive, hex_primitive, hex_primitive ])(s); | |
let colors = value.slice(1).map(hex => parseInt(hex, 16)); | |
return colors; | |
}; | |
hex_color("#5A4B3C"); // [90, 75, 60] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment