Source

trac-gviz / trac-dev / gviz / tracgviz / grammar.py

Full commit
#!/usr/bin/env python

# Copyright 2009-2011 Olemis Lang <olemis at gmail.com>
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

r"""Internal representation of operator precedence grammar used to parse
Google Visualization API Query Language expressions.

Copyright 2009-2011 Olemis Lang <olemis at gmail.com>
Licensed under the Apache License, Version 2.0 
"""
__author__ = 'Olemis Lang'

__all__ = '', ''

from pygments.token import *

from tracgviz.util.parsing import Any, EndMarker, gen_precedence, NonTerminal, \
    OperatorPrecedenceParser as Parser

# Grammar
# =======

GVIZ_QL_START_STATE = 'GVIZ_SQL'

def gen_gvizql_grammar():
  GVIZ_QL_SYMBOLS = [ 
      (Operator.Word.Boolean, 'and'), 
      (Operator.Word.Boolean, 'or'), 
      (Operator.Word.Boolean, 'not'), 
      (Number, Any), 
      (Name.Variable, Any), 
      (String, Any), 
      (Literal.Date, Any), 
      (Name.Constant, Any), 
      (Name.Builtin, Any), 
      (Name.Function, Any), 
      (Punctuation, ','), 
      (Punctuation, '('), 
      (Punctuation, ')'), 
      (Operator.Arithmetic, '+'), 
      (Operator.Arithmetic, '*'), 
      (Operator.Arithmetic, '-'), 
      (Operator.Arithmetic, '/'), 
      (Operator.Comparison, Any), 
      (Operator.Word.Comparison, Any), 
      (Keyword.Reserved, 'select'),
      (Keyword.Reserved, 'where'),
      (Keyword.Reserved, 'group by'),
      (Keyword.Reserved, 'pivot'),
      (Keyword.Reserved, 'order by'),
      (Keyword.Reserved, 'limit'),
      (Keyword.Reserved, 'offset'),
      (Keyword.Reserved, 'label'),
      (Keyword.Reserved, 'format'),
      (Keyword.Reserved, 'options'),
    ]

  _And, _Or, _Not, _Number, _Var, _Str, _Date, _Const, _Builtin, _Function, \
  _Comma, _OpenP, _CloseP, _Plus, _Mult, _Minus, _Div, _BoolOp, \
  _BoolWordOp, _Select, _Where, _GroupBy, _Pivot, _OrderBy, _Limit, _Offset, \
  _Label, _Format, _Options = GVIZ_QL_TERMINALS

  # GViz QL non-terminals
  GVIZQL, CLAUSE, SEQ, COL_SEQ, COLUMN, BOOL_EXPR, LABEL_SEQ, \
  LABEL_EXPR, VALUE, ARITHMETIC_EXPR, TERM, FACTOR, SIMPLE_EXPR, \
  BOOL_VALUE, BOOL_EXPR, OR_EXPR = [(NonTerminal, x) for x in (
    'GVIZQL', 'CLAUSE', 'SEQ', 'COLSEQ', 'COLUMN', 'BOOL_EXPR', 'LABELSEQ', \
    'LABEL_EXPR', 'VALUE', 'ARITHMETIC_EXPR', 'TERM', 'FACTOR', 'SIMPLE_EXPR', \
    'BOOL_VALUE', 'BOOL_EXPR', 'OR_EXPR' )]

  GVIZ_PRODUCTIONS = [
      # SQL clauses
      ('gvizql',  GVIZQL,     [ GVIZQL, (Whitespace, Any), CLAUSE ] ),
      ('',        GVIZQL,     [ CLAUSE ] ),
      ('select',  CLAUSE,     [ _Select, SEQ ] ),
      ('where',   CLAUSE,     [ _Where, BOOL_EXPR ] ),
      ('groupby', CLAUSE,     [ _GroupBy, COL_SEQ ] ),
      ('pivot',   CLAUSE,     [ _Pivot, COL_SEQ ] ),
      ('orderby', CLAUSE,     [ _OrderBy, SEQ ] ),
      ('limit',   CLAUSE,     [ _Limit, _Number ] ),
      ('offset',  CLAUSE,     [ _Offset, _Number ] ),
      ('label',   CLAUSE,     [ _Label, LABEL_SEQ ] ),
      ('format',  CLAUSE,     [ _Format, LABEL_SEQ ] ),
      ('options', CLAUSE,     [ _Options, COL_SEQ ] ),
      ('colseq',  COL_SEQ,    [ COL_SEQ , _Comma , COLUMN ] ),
      ('',        COL_SEQ,    [ COLUMN ] ),
      ('column',  COLUMN,     [ _Var ] ),
      ('lblseq',  LABEL_SEQ,  [ LABEL_SEQ, _Comma, LABEL_EXPR ] ),
      ('',        LABEL_SEQ,  [ LABEL_EXPR ] ),
      ('lblexpr', LABEL_EXPR, [ _Var, _Str ] ),

      # Boolean expressions
      ('boolexp', BOOL_EXPR,  [ BOOL_EXPR, _And, OR_EXPR ] ),
      ('',        BOOL_EXPR,  [ OR_EXPR ] ),
      ('orexp',   OR_EXPR,    [ OR_EXPR, _Or, BOOL_VALUE ] ),
      ('',        OR_EXPR,    [ BOOL_VALUE ] ),
      ('not',     BOOL_VALUE, [ _Not BOOL_VALUE ] ),
      ('cmp',     BOOL_VALUE, [ ARITHMETIC_EXPR, _BoolOp, ARITHMETIC_EXPR ] ),
      ('strcmp',  BOOL_VALUE, [ ARITHMETIC_EXPR, _BoolWordOp, ARITHMETIC_EXPR ] ),

      # Arithmetic expressions
      ('sum',     ARITHMETIC_EXPR,  [ ARITHMETIC_EXPR, _Plus, TERM ] ),
      ('sub',     ARITHMETIC_EXPR,  [ ARITHMETIC_EXPR, _Minus, TERM ] ),
      ('',        ARITHMETIC_EXPR,  [ TERM ] ),
      ('mult',    TERM,             [ TERM, _Mult, FACTOR ] ),
      ('',        TERM,             [ FACTOR ] ),
      ('div',     FACTOR,           [ FACTOR, _Div, SIMPLE_EXPR ] ),
      ('',        FACTOR,           [ SIMPLE_EXPR ] ),
      ('par',     SIMPLE_EXPR,      [ _OpenP, ARITHMETIC_EXPR, _CloseP ] ),
      ('',        SIMPLE_EXPR,      [ VALUE ] ),

      # Function calls
      ('bfunc',     VALUE, [ _Builtin, OpenP, CloseP ] ),
      ('func',      VALUE, [ _Function, OpenP, CloseP ] ),
      ('bfuncargs', VALUE, [ _Builtin, OpenP, SEQ, CloseP ] ),
      ('funcargs',  VALUE, [ _Function, OpenP, SEQ, CloseP ] ),
      ('seq',       SEQ, [ SEQ, _Comma, ARITHMETIC_EXPR ] ),
      ('',          SEQ, [ ARITHMETIC_EXPR ] ),

      # Literals and constants
      ('number',    VALUE, [ _Number ] ),
      ('var',       VALUE, [ _Var ] ),
      ('str',       VALUE, [ _Str ] ),
      ('date',      VALUE, [ _Date ] ),
      ('const',     VALUE, [ _Const ] ),
    ],

  #  1.   VALUE -> Number
  #  2.   VALUE -> Variable
  #  3.   VALUE -> String
  #  4.   VALUE -> Date
  #  5.   VALUE -> Constant
  #  6.   VALUE -> Builtin ( )
  #  7.   VALUE -> Builtin ( SUITE )
  #  8.   VALUE -> Function ( )
  #  9.   VALUE -> Function ( SUITE )
  #  10.  SUITE -> SUITE , ARITMETIC_EXPR
  #  10a. SUITE -> ARITMETIC_EXPR
  #  13.  ARITMETIC_EXPR -> ARITMETIC_EXPR + TERM
  #  14.  ARITMETIC_EXPR -> ARITMETIC_EXPR - TERM
  #  14a. ARITMETIC_EXPR -> TERM
  #  15.  TERM -> TERM * FACTOR
  #  15.a TERM -> FACTOR
  #  16.  FACTOR -> FACTOR / SIMPLE_EXPR
  #  16a. FACTOR -> SIMPLE_EXPR
  #  17.  SIMPLE_EXPR -> ( ARITHMETIC_EXPR )
  #  17a. SIMPLE_EXPR -> VALUE
  #  18.  BOOL_VALUE -> ARITHMETIC_EXPR Operator.Comparison ARITHMETIC_EXPR
  #  19.  BOOL_VALUE -> ARITHMETIC_EXPR Operator.Word.Comparison ARITHMETIC_EXPR
  #  20.  BOOL_VALUE -> not BOOL_VALUE
  #  21.  BOOL_EXPR -> BOOL_EXPR and OR_EXPR
  #  21a. BOOL_EXPR -> OR_EXPR
  #  22.  OR_EXPR -> OR_EXPR or BOOL_VALUE
  #  22a. OR_EXPR -> BOOL_VALUE

GVIZ_GRAMMAR_PRECEDENCE = {
    CloseP : {
        Parser.MorePrecedence : [Multiply, Add, CloseP, EndE],
      },
    Var : {
        Parser.MorePrecedence : [Multiply, Add, CloseP, EndE],
      },
    Multiply : {
        Parser.MorePrecedence : [Multiply, Add, CloseP, EndE],
        Parser.LessPrecedence : [OpenP, Var],
      },
    Add : {
        Parser.MorePrecedence : [Add, CloseP, EndE],
        Parser.LessPrecedence : [Multiply, OpenP, Var],
      },
    OpenP : {
        Parser.LessPrecedence : [OpenP, Var, Multiply, Add,],
        Parser.SamePrecedence : [CloseP, ],
      },
    EndE : {
        Parser.LessPrecedence : [OpenP, Var, Multiply, Add,],
      },
  }

GVIZ_GRAMMAR_PRECEDENCE = gen_precedence(GVIZ_GRAMMAR_PRECEDENCE) 

GVIZ_GRAMMAR_PRODUCTIONS = {
    (Name, Any) : {
        EndMarker : '6',
      },
    (Punctuation, ')') : {
        (NonTerminal, Any) : {
            (Punctuation, '(') : {
                EndMarker: '5',
              }
          }
      },
    (NonTerminal, Any) : {
        (Operator, '*') :{
            (NonTerminal, Any) : {
                EndMarker: '3',
              }
          },
        (Operator, '+') :{
            (NonTerminal, Any) : {
                EndMarker: '1',
              }
          },
      },
  }