EML BNF

EML BNF is an extension of an ad hoc version of SQL 89 for Gold parser.

    ! --------------------------------------------------------------------------------+++
    ! E-model language (EML)
    !
    ! An E-model prototype is implemented on top of relational database.
    ! Its full functions are implemented using hundreds of SQL procedures
    ! and functions. The idea is when a database system adds the E-model
    ! database to existing databases, then a user can query the database
    ! in the mixture of structured queries and E-model queries.
    ! EML implements such ideas to extend SQL language to support
    ! both structured and unstructured queries with various feature additions.
    !
    ! Update:
    !   03/29/2009
    !     Preliminary EML design
    !
    ! Note: This is a preliminary version of the EML based on the SQL 89 grammar
    ! at http://www.devincook.com/goldparser/grammars/index.htm.
    ! --------------------------------------------------------------------------------+++

    "Name"         = 'E-model language (EML)'
    "Author"       = 'Pilho Kim'
    "Version"      = '03/29/2009'
    "About"        = 'EML is an extended SQL language developed on top of E-model.'

    "Start Symbol" = <Query>

    ! =============================================================================
    ! Comments
    ! =============================================================================

    Comment Start = '/*'
    Comment End   = '*/'
    Comment Line  = '--'

    ! =============================================================================
    ! Terminals
    ! =============================================================================

    {String Ch 1}      = {Printable} - ["]
    {String Ch 2}      = {Printable} - ['']
    {Id Ch Standard}   = {Alphanumeric} + [_] + ['*']
    {Id Ch Extended}   = {Printable} - ['['] - [']']

    StringLiteral   = '"'{String Ch 1}*'"' | ''{String Ch 2}*''
    IntegerLiteral  = {Digit}+
    RealLiteral     = {Digit}+'.'{Digit}+

    ! =============================================================================
    ! EML namespace
    ! =============================================================================

    ! Extension for EML, allow * to specify whole database
    {EML Id Ch}   = {Letter} + ['_'] + ['*']

    !----- Identifiers in SQL are very complex.
    ! Id             = ({Letter}{Id Ch Standard}* | '['{Id Ch Extended}+']')  ('.'({Letter}{Id Ch Standard}* | '['{Id Ch Extended}+']'))?
    ! Support _* expression that specify the whole databases and tables
    Id             = ({EML Id Ch}{Id Ch Standard}* | '['{Id Ch Extended}+']')  ('.'({EML Id Ch}{Id Ch Standard}* | '['{Id Ch Extended}+']'))?

    ! =============================================================================
    ! Rules
    ! =============================================================================

    ! Support EndofStatement ';'
    <Query>       ::= <Alter Stm> <EndofStatement>
                    | <Create Stm> <EndofStatement>
                    | <Delete Stm> <EndofStatement>
                    | <Drop Stm> <EndofStatement>
                    | <Insert Stm> <EndofStatement>
                    | <Select Stm> <EndofStatement>
                    | <Update Stm> <EndofStatement>

    ! =============================================================================
    ! Table modification statements
    ! =============================================================================

    ! Support EndofStatement ';'
    <EndofStatement> ::= ';'
                       |


    ! <Alter Stm>   ::= ALTER TABLE Id ADD  COLUMN <Field Def List> <Constraint Opt>
    !                 | ALTER TABLE Id ADD  <Constraint>
    !                 | ALTER TABLE Id DROP COLUMN Id
    !                 | ALTER TABLE Id DROP CONSTRAINT Id

    ! Add * to table specification
    <Alter Stm>   ::= ALTER TABLE Id ADD  COLUMN <Field Def List> <Constraint Opt>
                    | ALTER TABLE Id ADD  <Constraint>
                    | ALTER TABLE Id DROP COLUMN Id
                    | ALTER TABLE Id DROP CONSTRAINT Id
                    | ALTER Id DROP COLUMN Id


    <Create Stm>  ::= CREATE <Unique> INDEX IntegerLiteral ON Id '(' <Order List> ')' <With Clause>
                    | CREATE TABLE Id '(' <ID List> ')' <Constraint Opt>

    <Unique>      ::= UNIQUE
                    |

    <With Clause> ::= WITH PRIMARY
                    | WITH DISALLOW NULL
                    | WITH IGNORE NULL
                    |

    <Field Def>   ::= Id <Type> NOT NULL
                    | Id <Type>

    <Field Def List> ::= <Field Def> ',' <Field Def List>
                       | <Field Def>

    <Type>  ::=  BIT
              |  DATE
              |  TIME
              |  TIMESTAMP
              |  DECIMAL
              |  REAL
              |  FLOAT
              |  SMALLINT
              |  INTEGER
              |  INTERVAL
              |  CHARACTER

    <Constraint Opt>  ::= <Constraint>
                        |

    <Constraint>      ::= CONSTRAINT Id <Constraint Type>
                        | CONSTRAINT Id

    <Constraint Type> ::= PRIMARY KEY '(' <Id List> ')'
                        | UNIQUE      '(' <Id List> ')'
                        | NOT NULL    '(' <Id List> ')'
                        | FOREIGN KEY '(' <Id List> ')' REFERENCES Id '(' <Id List> ')'

    <Drop Stm>        ::= DROP TABLE Id
                        | DROP INDEX Id ON Id

    ! =============================================================================
    ! Update database contents
    ! =============================================================================

    <Insert Stm>    ::= INSERT INTO Id '(' <Id List> ')' <Select Stm>
                      | INSERT INTO Id '(' <Id List> ')' VALUES '(' <Expr List> ')'

    <Update Stm>    ::= UPDATE Id SET <Assign List> <Where Clause> <When Clause>

    <Assign List>   ::= Id '=' <Expression> ',' <Assign List>
                      | Id '=' <Expression>

    <Delete Stm>    ::= DELETE FROM Id <Where Clause> <When Clause>

    ! =============================================================================
    ! Select Statement
    ! =============================================================================

    ! Add LIMIT
    <Select Stm>    ::= SELECT <Columns> <Into Clause> <From Clause> <Where Clause> <When Clause> <Group Clause> <Having Clause> <Order Clause> <Limit Clause>

    ! Modify to allow adding columns after *
    <Columns>       ::= <Restriction> '*'
                      | <Restriction> '*' ',' <Column List>
                      | <Restriction> <Column List>

    <Column List>   ::= <Column Item> ',' <Column List>
                      | <Column Item>

    ! Suuport AS
    <Column Item>   ::= <Column Source>
                      | <Column Source> AS Id      !ALIAS
                      | <Column Source> Id      !ALIAS

    ! Add EML path query
    <Column Source> ::= <Aggregate>
                      | Id
                      | <EML Pathquery>

    <Restriction>   ::= ALL
                      | DISTINCT
                      |

    ! Add ranking order
    <Aggregate>     ::= Count  '(' '*' ')'
                      | Count  '(' <Expression> ')'
                      | Avg    '(' <Expression> ')'
                      | Min    '(' <Expression> ')'
                      | Max    '(' <Expression> ')'
                      | StDev  '(' <Expression> ')'
                      | StDevP '(' <Expression> ')'
                      | Sum    '(' <Expression> ')'
                      | Var    '(' <Expression> ')'
                      | VarP   '(' <Expression> ')'

    ! Add EML path query
    <EML Pathquery> ::= R '(' <EML Pathelement> ',' <EML Pathelement> ',' <EML Pathelement> ')'
                  | R '(' <EML Pathquery> ',' <EML Pathelement> ',' <EML Pathelement> ')'
                  | R '(' <EML Pathelement> ',' <EML Pathelement> ',' <EML Pathquery> ')'
                  |

    <EML Pathelement> ::= StringLiteral
                    | StringLiteral '/' <EML Pathelement>
                    | '%' IntegerLiteral
                    | '*'

    ! Add semantic functions
    <EML Semantic Search>     ::= Antonym               '(' <Expression> ')'
                                | Similar               '(' <Expression> ')'
                                | Also                  '(' <Expression> ')'
                                | Attribute             '(' <Expression> ')'
                                | VerbGroup             '(' <Expression> ')'
                                | Participle            '(' <Expression> ')'
                                | Pertainym             '(' <Expression> ')'
                                | Derivation            '(' <Expression> ')'
                                | DomainCategory        '(' <Expression> ')'
                                | DomainMemberCategory  '(' <Expression> ')'
                                | DomainRegion          '(' <Expression> ')'
                                | DomainMemberRegion    '(' <Expression> ')'
                                | DomainUsage           '(' <Expression> ')'
                                | DomainMemberUsage     '(' <Expression> ')'
                                | Domain                '(' <Expression> ')'
                                | Member                '(' <Expression> ')'
                                | Hypernym              '(' <Expression> ')'
                                | Hyponym               '(' <Expression> ')'
                                | InstanceHypernym      '(' <Expression> ')'
                                | InstanceHyponym       '(' <Expression> ')'
                                | PartHolonym           '(' <Expression> ')'
                                | PartMeronym           '(' <Expression> ')'
                                | MemberHolonym         '(' <Expression> ')'
                                | MemberMeronym         '(' <Expression> ')'
                                | SubstanceHolonym      '(' <Expression> ')'
                                | SubstanceMeronym      '(' <Expression> ')'

    <Into Clause>   ::= INTO Id
                      |

    <From Clause>   ::= FROM <Id List> <Join Chain>

    <Join Chain>    ::= <Join> <Join Chain>
                      |

    <Join>          ::= INNER JOIN <Id List> ON Id '=' Id
                      | LEFT  JOIN <Id List> ON Id '=' Id
                      | RIGHT JOIN <Id List> ON Id '=' Id
                      |       JOIN <Id List> ON Id '=' Id


    <Where Clause>  ::= WHERE <Expression>
                      |

    <When Clause>  ::= WHEN <Expression>
                      |

    <Group Clause>  ::= GROUP BY <Id List>
                      |

    <Order Clause>  ::= ORDER BY <Order List>
                      |

    ! Change to include expression
    <Order List>    ::= <Expression> <Order Type> ',' <Order List>
                      | <Expression> <Order Type>

    <Order Type>    ::= ASC
                      | DESC
                      |

    <Having Clause> ::= HAVING <Expression>
                      |

    <Limit Clause> ::= LIMIT IntegerLiteral
                     |

    ! =============================================================================
    ! Expressions
    ! =============================================================================

    <Expression>  ::= <And Exp> OR <Expression>
                    | <And Exp>

    <And Exp>     ::= <Not Exp> AND <And Exp>
                    | <Not Exp>

    <Not Exp>     ::= NOT <Pred Exp>
                    | <Pred Exp>

    ! Add REGEXP
    ! Extend expresstion to include the range selection
    <Pred Exp>    ::= <Add Exp> BETWEEN <Add Exp> AND <Add Exp>
                    | <Add Exp> NOT BETWEEN <Add Exp> AND <Add Exp>
                    | <Value> IS NOT NULL
                    | <Value> IS NULL
                    | <Add Exp> REGEXP StringLiteral
                    | <Add Exp> LIKE StringLiteral
                    | <Add Exp> LIKE <EML Semantic Search>
                    | <Add Exp> IN   <Tuple>
                    | <Add Exp> '='  <Add Exp>
                    | <Add Exp> '<>' <Add Exp>
                    | <Add Exp> '!=' <Add Exp>
                    | <Add Exp> '>'  <Add Exp>
                    | <Add Exp> '>=' <Add Exp>
                    | <Add Exp> '<'  <Add Exp>
                    | <Add Exp> '<'  <Add Exp> '<' <Add Exp>
                    | <Add Exp> '<='  <Add Exp> '<' <Add Exp>
                    | <Add Exp> '<'  <Add Exp> '<=' <Add Exp>
                    | <Add Exp> '<=' <Add Exp>
                    | <Add Exp>

    <Add Exp>     ::= <Add Exp> '+' <Mult Exp>
                    | <Add Exp> '-' <Mult Exp>
                    | <Mult Exp>

    <Mult Exp>    ::= <Mult Exp> '*' <Negate Exp>
                    | <Mult Exp> '/' <Negate Exp>
                    | <Negate Exp>

    <Negate Exp>  ::= '-' <Value>
                    | <Value>

    ! Support function literals
    ! Add temporal expression
    <Value>       ::= <Tuple>
                    | ID
                    | IntegerLiteral
                    | RealLiteral
                    | StringLiteral
                    | <Function>
                    | NULL
                    | IntegerLiteral 'day'
                    | IntegerLiteral 'week'
                    | IntegerLiteral 'month'
                    | IntegerLiteral 'year'

    !---- Support specific function literals
    <Function> ::= Now '()'
                | Second  '()' | Second  '(' <Value> ')'
                | Minute  '()' | Minute  '(' <Value> ')'
                | Hour  '()' | Hour  '(' <Value> ')'
                | Day  '()' | Day  '(' <Value> ')'
                | Week  '()' | Week  '(' <Value> ')'
                | Month  '()' | Month  '(' <Value> ')'
                | Year    '()' | Year    '(' <Value> ')'
                | Curdate '()'
                | Current_time '()'
                | Curdate_timestamp '()'
                | Curtime '()'
                | Popularity '(' <Value> ')'

    <Tuple>       ::= '(' <Select Stm> ')'
                    | '(' <Expr List> ')'

    <Expr List>  ::= <Expression> ',' <Expr List>
                   | <Expression>

    <Id List>     ::= <Id Member> ',' <Id List>
                    | <Id Member>

    ! <Id Member>   ::= Id
    !                | Id Id

    ! Support 'AS' and sub query
    <Id Member>   ::= Id
                    | Id Id
                    | Id AS Id
                    | '(' <Select Stm> ')'
                    | '(' <Select Stm> ')' Id
                    | '(' <Select Stm> ')' AS Id