Skip to content

Instantly share code, notes, and snippets.

@huytd
Last active July 20, 2018 01:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save huytd/9788d069db85ea024f35daba58019a0a to your computer and use it in GitHub Desktop.
Save huytd/9788d069db85ea024f35daba58019a0a to your computer and use it in GitHub Desktop.
Hex color parsing using parser combinator
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
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