Skip to content

Instantly share code, notes, and snippets.

@gomezcabo
Last active February 16, 2021 09:35
Show Gist options
  • Save gomezcabo/20930ac674783d922b11eda55b0dfd5a to your computer and use it in GitHub Desktop.
Save gomezcabo/20930ac674783d922b11eda55b0dfd5a to your computer and use it in GitHub Desktop.
Simple query to SQL parser
// ================================
// Simple query to SQL parser
//
// Copy and paste to https://pegjs.org/online
//
// It parses expressions like:
//
// (flag == True) AND (name == 'Paco' OR (name LIKE '%garcia%') OR (age > 18 AND age <= 45))
//
// ================================
start = ex:Expression { return "SELECT * FROM myTable WHERE " + ex; }
Expression
= head:Term tail:(_ ("AND" / "OR") _ Term)* {
return tail.reduce(function(result, element) {
if (element[1] === "OR") { return "(" + result + " OR " + element[3] + ")"; }
if (element[1] === "AND") { return "(" + result + " AND " + element[3] + ")"; }
}, head);
}
Term
= head:Factor tail:(_ ("AND" / "OR") _ Factor)* {
return tail.reduce(function(result, element) {
if (element[1] === "OR") { return "(" + result + " OR " + element[3] + ")"; }
if (element[1] === "AND") { return "(" + result + " AND " + element[3] + ")"; }
}, head);
}
/ Factor
Factor
= "(" _ expr:Expression _ ")" { return expr; }
/ Condition
Condition
= id:Identifier _ op:Operator _ val:Value { return "'" + id + "' " + op + " " + val; }
Operator = _ ("!=" / "<=" / "<" / "==" / ">=" / ">" / "LIKE") _ { return text() }
Boolean
= "True" / "False"
Identifier
= [a-zA-z][a-zA-Z0-9]* { return text(); }
Value
= String / Integer / Boolean { return text(); }
String
= "\"" [a-zA-Z0-9%]* "\"" { return text(); }
/ "'" [a-zA-Z0-9%]* "'" { return text(); }
Integer
= [0-9]+ { return parseInt(text(), 10); }
_ "whitespace"
= [ \t\n\r]*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment