Last active
August 29, 2015 14:08
-
-
Save JoshClose/b1635db1ba55129e0a29 to your computer and use it in GitHub Desktop.
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
using Irony.Parsing; | |
namespace Irony.Samples.SQLite | |
{ | |
[Language( "SQLite", "3", "SQLite Grammar" )] | |
// ReSharper disable once InconsistentNaming | |
public class SQLiteGrammar : Grammar | |
{ | |
public SQLiteGrammar() : base( false ) | |
{ | |
var lineComment = new CommentTerminal( "line_comment", "--", "\r\n", "\n" ); | |
var comment = new CommentTerminal( "comment", "/*", "*/" ); | |
NonGrammarTerminals.Add( comment ); | |
NonGrammarTerminals.Add( lineComment ); | |
var numericLiteral = new NumberLiteral( "number" ); | |
var stringLiteral = new StringLiteral( "string", "'", StringOptions.AllowsDoubledQuote ); | |
var blobLiteral = new NonTerminal( "blob" ); | |
blobLiteral.Rule = "x" + stringLiteral; | |
// Covers normal identifiers (abc) and quoted id's ([abc d], "abc d") | |
var idSimple = TerminalFactory.CreateSqlExtIdentifier( this, "idSimple" ); | |
var comma = ToTerm( "," ); | |
var dot = ToTerm( "." ); | |
var semi = ToTerm( ";" ); | |
// ReSharper disable InconsistentNaming | |
var ABORT = ToTerm( "ABORT" ); | |
var ACTION = ToTerm( "ACTION" ); | |
var ADD = ToTerm( "ADD" ); | |
var AFTER = ToTerm( "AFTER" ); | |
var ALL = ToTerm( "ALL" ); | |
var ALTER = ToTerm( "ALTER" ); | |
var ANALYZE = ToTerm( "ANALYZE" ); | |
var AND = ToTerm( "AND" ); | |
var AS = ToTerm( "AS" ); | |
var ASC = ToTerm( "ASC" ); | |
var ATTACH = ToTerm( "ATTACH" ); | |
var AUTOINCREMENT = ToTerm( "AUTOINCREMENT" ); | |
var BEFORE = ToTerm( "BEFORE" ); | |
var BEGIN = ToTerm( "BEGIN" ); | |
var BETWEEN = ToTerm( "BETWEEN" ); | |
var BY = ToTerm( "BY" ); | |
var CASCADE = ToTerm( "CASCADE" ); | |
var CASE = ToTerm( "CASE" ); | |
var CAST = ToTerm( "CAST" ); | |
var CHECK = ToTerm( "CHECK" ); | |
var COLLATE = ToTerm( "COLLATE" ); | |
var COLUMN = ToTerm( "COLUMN" ); | |
var COMMIT = ToTerm( "COMMIT" ); | |
var CONFLICT = ToTerm( "CONFLICT" ); | |
var CONSTRAINT = ToTerm( "CONSTRAINT" ); | |
var CREATE = ToTerm( "CREATE" ); | |
var CROSS = ToTerm( "CROSS" ); | |
var CURRENT_DATE = ToTerm( "CURRENT_DATE" ); | |
var CURRENT_TIME = ToTerm( "CURRENT_TIME" ); | |
var CURRENT_TIMESTAMP = ToTerm( "CURRENT_TIMESTAMP" ); | |
var DATABASE = ToTerm( "DATABASE" ); | |
var DEFAULT = ToTerm( "DEFAULT" ); | |
var DEFERRABLE = ToTerm( "DEFERRABLE" ); | |
var DEFERRED = ToTerm( "DEFERRED" ); | |
var DELETE = ToTerm( "DELETE" ); | |
var DESC = ToTerm( "DESC" ); | |
var DETACH = ToTerm( "DETACH" ); | |
var DISTINCT = ToTerm( "DISTINCT" ); | |
var DROP = ToTerm( "DROP" ); | |
var EACH = ToTerm( "EACH" ); | |
var ELSE = ToTerm( "ELSE" ); | |
var END = ToTerm( "END" ); | |
var ESCAPE = ToTerm( "ESCAPE" ); | |
var EXCEPT = ToTerm( "EXCEPT" ); | |
var EXCLUSIVE = ToTerm( "EXCLUSIVE" ); | |
var EXISTS = ToTerm( "EXISTS" ); | |
var EXPLAIN = ToTerm( "EXPLAIN" ); | |
var FAIL = ToTerm( "FAIL" ); | |
var FOR = ToTerm( "FOR" ); | |
var FOREIGN = ToTerm( "FOREIGN" ); | |
var FROM = ToTerm( "FROM" ); | |
var FULL = ToTerm( "FULL" ); | |
var GLOB = ToTerm( "GLOB" ); | |
var GROUP = ToTerm( "GROUP" ); | |
var HAVING = ToTerm( "HAVING" ); | |
var IF = ToTerm( "IF" ); | |
var IGNORE = ToTerm( "IGNORE" ); | |
var IMMEDIATE = ToTerm( "IMMEDIATE" ); | |
var IN = ToTerm( "IN" ); | |
var INDEX = ToTerm( "INDEX" ); | |
var INDEXED = ToTerm( "INDEXED" ); | |
var INITIALLY = ToTerm( "INTIALLY" ); | |
var INNER = ToTerm( "INNER" ); | |
var INSERT = ToTerm( "INSERT" ); | |
var INSTEAD = ToTerm( "INSTEAD" ); | |
var INTERSECT = ToTerm( "INTERSECT" ); | |
var INTO = ToTerm( "INTO" ); | |
var IS = ToTerm( "IS" ); | |
var ISNULL = ToTerm( "ISNULL" ); | |
var JOIN = ToTerm( "JOIN" ); | |
var KEY = ToTerm( "KEY" ); | |
var LEFT = ToTerm( "LEFT" ); | |
var LIKE = ToTerm( "LIKE" ); | |
var LIMIT = ToTerm( "LIMIT" ); | |
var MATCH = ToTerm( "MATCH" ); | |
var NATURAL = ToTerm( "NATURAL" ); | |
var NO = ToTerm( "NO" ); | |
var NOT = ToTerm( "NOT" ); | |
var NOTNULL = ToTerm( "NOTNULL" ); | |
var NULL = ToTerm( "NULL" ); | |
var OF = ToTerm( "OF" ); | |
var OFFSET = ToTerm( "OFFSET" ); | |
var ON = ToTerm( "ON" ); | |
var OR = ToTerm( "OR" ); | |
var ORDER = ToTerm( "ORDER" ); | |
var OUTER = ToTerm( "OUTER" ); | |
var PLAN = ToTerm( "PLAN" ); | |
var PRAGMA = ToTerm( "PRAGMA" ); | |
var PRIMARY = ToTerm( "PRIMARY" ); | |
var QUERY = ToTerm( "QUERY" ); | |
var RAISE = ToTerm( "RAISE" ); | |
var RECURSIVE = ToTerm( "RECURSIVE" ); | |
var REFERENCES = ToTerm( "REFERENCES" ); | |
var REGEXP = ToTerm( "REGEXP" ); | |
var REINDEX = ToTerm( "REINDEX" ); | |
var RELEASE = ToTerm( "RELEASE" ); | |
var RENAME = ToTerm( "RENAME" ); | |
var REPLACE = ToTerm( "REPLACE" ); | |
var RESTRICT = ToTerm( "RESTRICT" ); | |
var RIGHT = ToTerm( "RIGHT" ); | |
var ROLLBACK = ToTerm( "ROLLBACK" ); | |
var ROW = ToTerm( "ROW" ); | |
var ROWID = ToTerm( "ROWID" ); | |
var SAVEPOINT = ToTerm( "SAVEPOINT" ); | |
var SELECT = ToTerm( "SELECT" ); | |
var SET = ToTerm( "SET" ); | |
var TABLE = ToTerm( "TABLE" ); | |
var TEMP = ToTerm( "TEMP" ); | |
var TEMPORARY = ToTerm( "TEMPORARY" ); | |
var THEN = ToTerm( "THEN" ); | |
var TO = ToTerm( "TO" ); | |
var TRANSACTION = ToTerm( "TRANSACTION" ); | |
var TRIGGER = ToTerm( "TRIGGER" ); | |
var UNION = ToTerm( "UNION" ); | |
var UNIQUE = ToTerm( "UNIQUE" ); | |
var UPDATE = ToTerm( "UPADTE" ); | |
var USING = ToTerm( "USING" ); | |
var VACUUM = ToTerm( "VACUUM" ); | |
var VALUES = ToTerm( "VALUES" ); | |
var VIEW = ToTerm( "VIEW" ); | |
var VIRTUAL = ToTerm( "VIRTUAL" ); | |
var WHEN = ToTerm( "WHEN" ); | |
var WHERE = ToTerm( "WHERE" ); | |
var WITH = ToTerm( "WITH" ); | |
var WITHOUT = ToTerm( "WITHOUT" ); | |
// ReSharper restore InconsistentNaming | |
var sqlStmtList = new NonTerminal( "sql-stmt-list" ); | |
var sqlStmt = new NonTerminal( "sql-stmt" ); | |
var alterTableStmt = new NonTerminal( "alter-table-stmt" ); | |
var analyzeStmt = new NonTerminal( "analyze-stmt" ); | |
var attachStmt = new NonTerminal( "attach-stmt" ); | |
var beginStmt = new NonTerminal( "begin-stmt" ); | |
var commitStmt = new NonTerminal( "commit-stmt" ); | |
var rollbackStmt = new NonTerminal( "rollback-stmt" ); | |
var savepointStmt = new NonTerminal( "savepoint-stmt" ); | |
var releaseStmt = new NonTerminal( "release-stmt" ); | |
var createIndexStmt = new NonTerminal( "create-index-stmt" ); | |
var indexedColumn = new NonTerminal( "indexed-column" ); | |
var createTableStmt = new NonTerminal( "create-table-stmt" ); | |
var columnDef = new NonTerminal( "column-def" ); | |
var typeName = new NonTerminal( "type-name" ); | |
var columnConstraint = new NonTerminal( "column-constraint" ); | |
var signedNumber = new NonTerminal( "signed-number" ); | |
var tableConstraint = new NonTerminal( "table-constraint" ); | |
var foreignKeyClause = new NonTerminal( "foreign-key-clause" ); | |
var conflictClause = new NonTerminal( "conflict-clause" ); | |
var createTriggerStmt = new NonTerminal( "create-trigger-stmt" ); | |
var createViewStmt = new NonTerminal( "create-view-stmt" ); | |
var createVirtualTableStmt = new NonTerminal( "create-virtual-table-stmt" ); | |
var withClause = new NonTerminal( "with-clause" ); | |
var cteTableName = new NonTerminal( "cte-table-name" ); | |
var recursiveCte = new NonTerminal( "recursive-cte" ); | |
var commonTableExpression = new NonTerminal( "common-table-expression" ); | |
var deleteStmt = new NonTerminal( "delete-stmt" ); | |
var deleteStmtLimited = new NonTerminal( "delete-stmt-limited" ); | |
var detachStmt = new NonTerminal( "detach-stmt" ); | |
var dropIndexStmt = new NonTerminal( "drop-index-stmt" ); | |
var dropTableStmt = new NonTerminal( "drop-table-stmt" ); | |
var dropTriggerStmt = new NonTerminal( "drop-trigger-stmt" ); | |
var dropViewStmt = new NonTerminal( "drop-view-stmt" ); | |
var expr = new NonTerminal( "expr" ); | |
var raiseFunction = new NonTerminal( "raise-function" ); | |
var literalValue = new NonTerminal( "literal-value" ); | |
// Handled already by 'number'. | |
//var numericLiteral = new NonTerminal( "numeric-literal" ); | |
var insertStmt = new NonTerminal( "insert-stmt" ); | |
var pragmaStmt = new NonTerminal( "pragma-stmt" ); | |
var pragmaValue = new NonTerminal( "pragma-value" ); | |
var reindexStmt = new NonTerminal( "reindex-stmt" ); | |
var selectStmt = new NonTerminal( "select-stmt" ); | |
var joinClause = new NonTerminal( "join-clause" ); | |
var selectCore = new NonTerminal( "select-core" ); | |
var factoredSelectStmt = new NonTerminal( "factoredSelectStmt" ); | |
var simpleSelectStmt = new NonTerminal( "simple-select-stmt" ); | |
var compoundSelectStmt = new NonTerminal( "compound-select-stmt" ); | |
var tableOrSubquery = new NonTerminal( "table-or-subquery" ); | |
var resultColumn = new NonTerminal( "result-column" ); | |
var joinOperator = new NonTerminal( "join-operator" ); | |
var joinConstraint = new NonTerminal( "join-constraint" ); | |
var orderingTerm = new NonTerminal( "ordering-term" ); | |
var compoundOperator = new NonTerminal( "compound-operator" ); | |
var updateStmt = new NonTerminal( "update-stmt" ); | |
var updateStmtLimited = new NonTerminal( "update-stmt-limited" ); | |
var qualifiedTableName = new NonTerminal( "qualified-table-name" ); | |
var vacuumStmt = new NonTerminal( "vacuum-stmt" ); | |
// Handled already by CommentTerminal(). | |
//var commentSyntax = new NonTerminal( "comment-syntax" ); | |
var id = new NonTerminal( "id" ); | |
var idSimpleListCommaPlus = new NonTerminal( "idSimpleListCommaPlus" ); | |
var binaryOperator = new NonTerminal( "binaryOperator" ); | |
var unaryOperator = new NonTerminal( "unaryOperator" ); | |
var binaryExpr = new NonTerminal( "binaryExpr" ); | |
var unaryExpr = new NonTerminal( "unaryExpr" ); | |
var selectRestrictOpt = new NonTerminal( "selectRestrictOpt" ); | |
var resultColumnListCommaPlus = new NonTerminal( "resultColumnListCommaPlus" ); | |
var columnAliasOpt = new NonTerminal( "columnAliasOpt" ); | |
var asOpt = new NonTerminal( "asOpt" ); | |
var fromClause = new NonTerminal( "fromClause" ); | |
var tableOrSubqueryListCommaPlus = new NonTerminal( "tableOrSubqueryListCommaPlus" ); | |
var indexedClause = new NonTerminal( "indexedClause" ); | |
var naturalOpt = new NonTerminal( "naturalOpt" ); | |
var joinType = new NonTerminal( "joinType" ); | |
var outerOpt = new NonTerminal( "outerOpt" ); | |
var whereClause = new NonTerminal( "whereClause" ); | |
var groupClause = new NonTerminal( "groupClause" ); | |
var exprListCommaPlus = new NonTerminal( "exprListCommaPlus" ); | |
var exprListCommaPlusParen = new NonTerminal( "exprListCommaPlusParen" ); | |
var exprListCommaPlusParenListCommaPlus = new NonTerminal( "exprListCommaPlusParenListCommaPlus" ); | |
Root = sqlStmtList; | |
// Identifiers | |
id.Rule = MakePlusRule( id, dot, idSimple ); | |
idSimpleListCommaPlus.Rule = MakePlusRule( idSimpleListCommaPlus, comma, idSimple ); | |
// Operators | |
binaryOperator.Rule = ToTerm( "||" ) | "*" | "/" | "%" | "+" | "-" | "<<" | ">>" | "&" | "|" | "<" | "<=" | ">" | ">=" | "=" | "==" | "!=" | "<>" | |
| IS | IS + PreferShiftHere() + NOT | IN | LIKE | GLOB | MATCH | REGEXP | AND | OR; | |
unaryOperator.Rule = ToTerm( "-" ) | "+" | "~" | NOT; | |
// Optional | |
asOpt.Rule = Empty | AS; | |
columnAliasOpt.Rule = Empty | asOpt + idSimple; | |
selectRestrictOpt.Rule = Empty | DISTINCT | ALL; | |
naturalOpt.Rule = Empty | NATURAL; | |
outerOpt.Rule = Empty | OUTER; | |
// SQLite BNF | |
// sql-stmt-list | |
sqlStmtList.Rule = MakeStarRule( sqlStmtList, semi, sqlStmt ); | |
// sql-stmt | |
sqlStmt.Rule = selectStmt; | |
// expr | |
expr.Rule = literalValue | |
| id | |
| unaryExpr | |
| binaryExpr | |
; | |
unaryExpr.Rule = unaryOperator + expr; | |
binaryExpr.Rule = expr + binaryOperator + expr; | |
exprListCommaPlus.Rule = MakePlusRule( exprListCommaPlus, comma, expr ); | |
exprListCommaPlusParen.Rule = "(" + exprListCommaPlus + ")"; | |
exprListCommaPlusParenListCommaPlus.Rule = MakePlusRule( exprListCommaPlus, comma, exprListCommaPlusParen ); | |
// literal-value | |
literalValue.Rule = numericLiteral | |
| stringLiteral | |
| blobLiteral | |
| NULL | |
| CURRENT_TIME | |
| CURRENT_DATE | |
| CURRENT_TIMESTAMP; | |
// select-stmt | |
selectStmt.Rule = selectCore; | |
// join-clause | |
joinClause.Rule = tableOrSubquery + joinOperator + tableOrSubquery + joinConstraint; | |
// select-core | |
selectCore.Rule = SELECT + selectRestrictOpt + resultColumnListCommaPlus + fromClause + whereClause + groupClause | |
| VALUES + exprListCommaPlusParenListCommaPlus; | |
fromClause.Rule = Empty | |
| FROM + tableOrSubqueryListCommaPlus | |
| FROM + joinClause; | |
whereClause.Rule = Empty | WHERE + expr; | |
groupClause.Rule = Empty | |
| GROUP + BY + exprListCommaPlus | |
| GROUP + BY + exprListCommaPlus + HAVING + expr; | |
// table-or-subquery | |
tableOrSubquery.Rule = id + columnAliasOpt + indexedClause | |
| "(" + ( tableOrSubqueryListCommaPlus | joinClause ) + ")" | |
| "(" + selectStmt + ")" + columnAliasOpt; | |
tableOrSubqueryListCommaPlus.Rule = MakePlusRule( tableOrSubqueryListCommaPlus, comma, tableOrSubquery ); | |
indexedClause.Rule = Empty | INDEXED + BY + idSimple | NOT + INDEXED; | |
// result-column | |
resultColumn.Rule = "*" | |
| idSimple + PreferShiftHere() + dot + "*" | |
| expr + columnAliasOpt; | |
resultColumnListCommaPlus.Rule = MakePlusRule( resultColumnListCommaPlus, comma, resultColumn ); | |
// join-operator | |
joinOperator.Rule = naturalOpt + joinType + JOIN; | |
joinType.Rule = Empty | |
| LEFT + outerOpt | |
| INNER | |
| CROSS; | |
// join-constraint | |
joinConstraint.Rule = Empty | |
| ON + expr | |
| USING + "(" + idSimpleListCommaPlus + ")"; | |
RegisterOperators( 10, "||" ); | |
RegisterOperators( 9, "*", "/", "%" ); | |
RegisterOperators( 8, "+", "-" ); | |
RegisterOperators( 7, "<<", ">>", "&", "|" ); | |
RegisterOperators( 6, "<", "<=", ">", ">=" ); | |
RegisterOperators( 5, "=", "==", "!=", "<>" ); | |
RegisterOperators( 5, IS, /*IS + NOT,*/ IN, LIKE, GLOB, MATCH, REGEXP ); | |
RegisterOperators( 4, AND ); | |
RegisterOperators( 3, OR ); | |
MarkPunctuation( ",", "(", ")" ); | |
MarkPunctuation( asOpt ); | |
MarkTransient( selectStmt, expr, asOpt, columnAliasOpt, unaryOperator, selectRestrictOpt ); | |
binaryOperator.SetFlag( TermFlags.InheritPrecedence ); | |
// TODO: Double check that all the parens are in code here. | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment