Skip to content

Instantly share code, notes, and snippets.

@insin
Last active May 30, 2023 19:51
Show Gist options
  • Save insin/85e50561cc10757c2fc1b56254f48994 to your computer and use it in GitHub Desktop.
Save insin/85e50561cc10757c2fc1b56254f48994 to your computer and use it in GitHub Desktop.
PEG.js grammar for parsing input column ranges. Try it at http://pegjs.org/online
/**
* Accepts column ranges expressed using A-Z column names, or 1-based numbers.
*
* Returns a list of column numbers.
*
* e.g. A,B,D-F outputs [1,2,4,5,6]
*/
{
var baseCharCode = 'A'.charCodeAt(0) - 1 // 1-based
function excelCol(colName) {
colName = colName.toUpperCase()
var index = 0
for (var i = 0, pow = colName.length - 1; i < colName.length; i++, pow--) {
index += Math.pow(26, pow) * (colName.charCodeAt(i) - baseCharCode)
}
return index
}
function range(start, end) {
if (end < start) {
expected('a valid column range')
}
var result = []
while (end >= start) result.push(start++)
return result
}
}
Input
= head:Item tail:(_ "," _ item:Item {return item})* {
return head.concat(
// Flatten any additional columns given
tail.reduce(function(result, item) {
return result.concat(item)
}, [])
).sort(function(a, b) { return a - b })
}
Item
= left:Column _ "-" _ right:Column { return range(left, right) }
/ col:Column { return [col] }
Column "a column letter (starting from A) or number (starting from 1)"
= chars:[A-Z]i+ { return excelCol(chars.join('')) }
/ digits:[0-9]+ {
if (digits.join('') === '0') {
expected('column number to be 1 or more')
}
return Number(digits.join(''))
}
_ "whitespace"
= [ \t\n\r]*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment