예제 #1
0
def expression_parser():
  """A function returning a (pyparsing) parser for parsing C expressions.

  Returns:
    a (pyparsing) parser for parsing C expressions.
  """
  precedence = []
  for operators, arity, associativity in _PRECEDENCE:
    if arity <= 2:
      operators = pyparsing.Or(map(pyparsing.Literal, operators))
    else:
      operators = tuple(map(pyparsing.Literal, operators))
    precedence.append((
        operators,
        arity,
        associativity,
        _construct_operator(arity),
    ))
  expression = pyparsing.Forward()
  # pylint: disable=expression-not-assigned
  expression << pyparsing.infixNotation(
      baseExpr=_base_or_array_expression(expression),
      opList=precedence,
      lpar=pyparsing.NoMatch(),
      rpar=pyparsing.NoMatch(),
  )
  expression.ignore(pyparsing.cppStyleComment)
  return expression
예제 #2
0
    def _make_matcher_element(self):
        # Handle the case where use_current_match is True.
        if self.use_current_match is True:
            current_match = self.current_match
            if current_match is None:
                result = pyparsing.NoMatch()
            elif current_match == "":
                result = pyparsing.Empty()
            else:
                result = pyparsing.Literal(self.current_match)

            # Set the element's attributes and return it.
            return self._set_matcher_element_attributes(result)

        # Otherwise build a list of next possible literals. Make the required stack
        # of child-parent pairs.
        stack = []
        p1, p2 = self, self.parent
        while p1 and p2:
            stack.append((p1, p2))

            # Move both pivots further up the tree.
            p1 = p1.parent
            p2 = p2.parent

        # Build a list of next literals using the stack.
        next_literals, _ = _collect_next_literals(stack, 0, True, False)

        # De-duplicate the list.
        next_literals = set(next_literals)

        word = pyparsing.Regex(_word_regex_str, re.UNICODE)
        if next_literals:
            # Check if there is a next dictation literal. If there is, only match
            # one word for this expansion.
            if _word_regex_str in next_literals:
                result = word

            # Otherwise build an element to match one or more words stopping on
            # any of the next literals so that they aren't matched as dictation.
            else:
                next_literals = list(map(pyparsing.Literal, next_literals))
                result = pyparsing.OneOrMore(
                    word, stopOn=pyparsing.Or(next_literals))
        else:
            # Handle the case of no literals ahead by allowing one or more Unicode
            # words without restrictions.
            result = pyparsing.OneOrMore(word)

        return self._set_matcher_element_attributes(result)
예제 #3
0
    def __init__(self,
                 base_freq=440.0,
                 amplitude=.5,
                 max_gain=10.,
                 min_gain=-200.,
                 new_scale='C/a',
                 clef='violin'):

        # an important constant value for the conversion of musical halt tone steps to frequency values
        # is the twelfth root of 2
        self.__root__ = 1.0594630943592952645618252949463  # (2 ** (1 / 12))

        # *** parser definitions ***
        # helper
        no_whites = pp.NotAny(pp.White())
        tok_end = (pp.StringEnd() | pp.LineEnd()).suppress()

        # numbers
        real = pp.Combine(
            pp.Word(pp.nums) +
            pp.Optional(pp.Char(',.') + pp.Word(pp.nums))).setParseAction(
                lambda t: float(t[0].replace(',', '.')))

        integer = (pp.Optional(pp.Literal('-')) +
                   pp.Word(pp.nums)).setParseAction(
                       lambda t: int(t[0] + t[1]) if len(t) > 1 else int(t[0]))

        # signs
        must_sign = pp.Char('+-').setParseAction(lambda t: float(t[0] + '1'))
        may_sign = pp.Optional(pp.Char('+-')).setParseAction(
            lambda t: float(t[0] + '1' if len(t) > 0 else '1'))

        # note value cents
        cent = (must_sign + no_whites +
                real).setParseAction(lambda t: t[0] * t[1] / 100)

        # helpers for the note name parser
        note_name_offset = {
            'C': -9,
            'D': -7,
            'E': -5,
            'F': -4,
            'G': -2,
            'A': 0,
            'B': 2,
        }
        note_name = pp.Char('CDEFGABcdefgab').setParseAction(
            lambda t: note_name_offset[t[0]
                                       if t[0] in 'CDEFGAB' else t[0].upper()])

        flat_sharp = pp.Char('#b').setParseAction(lambda t: 1
                                                  if t[0] == '#' else -1)
        octave = pp.Char('0123456789').setParseAction(lambda t:
                                                      (int(t[0]) - 4) * 12)
        full_note = (note_name + no_whites +
                     pp.Optional(pp.FollowedBy(flat_sharp) + flat_sharp) +
                     no_whites + pp.FollowedBy(octave) +
                     octave).setParseAction(lambda t: sum(t))

        self.note_name_parser = (
            full_note + pp.Optional(pp.White()).suppress() +
            pp.Optional(cent) + tok_end
        ).setParseAction(lambda t: float(sum(t))).setResultsName('note_value')

        # frequency parsers
        hertz = real + pp.Literal('Hz').suppress()

        self.frequency_parser = (hertz + tok_end).setParseAction(
            lambda t: float(t[0])).setResultsName('frequency')

        self.base_freq_parser = (
            full_note + pp.Literal('=').suppress() + hertz + tok_end
        ).setParseAction(lambda t: t[1] * (1.0594630943592952645618252949463**
                                           -t[0])).setResultsName('base_freq')

        # parses a string like "sc -7:b" into a musical half tone step (using the MusicConverter.set method)
        sign = (pp.Keyword('##') | pp.Keyword('bb') | pp.Keyword('#')
                | pp.Keyword('b') | pp.Keyword('n') | pp.Keyword('_'))
        self.score_parser = (integer + pp.Literal(':').suppress() + sign +
                             tok_end).setResultsName('notation')

        # amplitude parser
        self.amp_parser = (
            real + pp.Literal('%').suppress() + tok_end
        ).setParseAction(lambda t: float(t[0])).setResultsName('amplitude')

        self.gain_parser = (
            may_sign + real + pp.Literal('dB').suppress() + tok_end
        ).setParseAction(lambda t: float(t[0] * t[1])).setResultsName('gain')

        # clef parser
        self.clef_parser = (pp.Keyword('violin') | pp.Keyword('alto')
                            | pp.Keyword('bass')).setResultsName('clef')

        # key parser
        key_token = pp.NoMatch()
        for key in self.keys:
            key_token = key_token | pp.Keyword(key)

        self.key_parser = (key_token).setResultsName('key')

        # complete parser
        self.input_parser = self.note_name_parser | \
                            self.frequency_parser | \
                            self.base_freq_parser | \
                            self.amp_parser | \
                            self.gain_parser | \
                            self.clef_parser | \
                            self.key_parser | \
                            self.score_parser

        # *** initializations ***
        self.__note_value__ = 0.
        self.__base_freq__ = 440.
        self.base_freq = base_freq

        self.key = new_scale
        self.__names__ = 'C D EF G A B'
        self.clef = clef
        self.__clef__ = 'violin'

        self.max_gain = max_gain
        self.min_gain = min_gain
        self.amplitude = amplitude
예제 #4
0
class BaseQuery(metaclass=ABCMeta):
    """Query abstract class.

    All backends query classes must inherit, directly or indirectly, from this one.
    """

    grammar = pyparsing.NoMatch()  # This grammar will never match.
    """:py:class:`pyparsing.ParserElement`: derived classes must define their own pyparsing grammar and set this class
    attribute accordingly."""
    def __init__(self, config):
        """Query constructor.

        Arguments:
            config (dict): a dictionary with the parsed configuration file.

        """
        self.config = config
        self.logger = logging.getLogger('.'.join(
            (self.__module__, self.__class__.__name__)))
        self.logger.trace('Backend %s created with config: %s',
                          type(self).__name__, config)

    def execute(self, query_string):
        """Build and execute the query, return the NodeSet of FQDN hostnames that matches.

        Arguments:
            query_string (str): the query string to be parsed and executed.

        Returns:
            ClusterShell.NodeSet.NodeSet: with the FQDNs of the matching hosts.

        """
        self._build(query_string)
        return self._execute()

    @abstractmethod
    def _execute(self):
        """Execute the already parsed query and return the NodeSet of FQDN hostnames that matches.

        Returns:
            ClusterShell.NodeSet.NodeSet: with the FQDNs of the matching hosts.

        """

    @abstractmethod
    def _parse_token(self, token):
        """Recursively interpret the tokens returned by the grammar parsing.

        Arguments:
            token (pyparsing.ParseResults): a single token returned by the grammar parsing.

        """

    def _build(self, query_string):
        """Parse the query string according to the grammar and build the query for later execution.

        Arguments:
            query_string (str): the query string to be parsed.

        """
        self.logger.trace('Parsing query: %s', query_string)
        parsed = self.grammar.parseString(query_string.strip(), parseAll=True)
        self.logger.trace('Parsed query: %s', parsed)
        for token in parsed:
            self._parse_token(token)
예제 #5
0
파일: expansions.py 프로젝트: daanzu/pyjsgf
 def _make_matcher_element(self):
     return pyparsing.NoMatch().setParseAction(self._parse_action)
예제 #6
0
#!/usr/bin/env python
from __future__ import absolute_import
from .annotator import Annotator, AnnoTier, AnnoSpan
import re
import pyparsing as pypar


def word_token_regex(disallowed_delimiter):
    return pypar.Regex(r"[^\s\n" + re.escape(disallowed_delimiter) + r"]+")


pypar.ParserElement.setDefaultWhitespaceChars(" \t")
table_parser = pypar.NoMatch()
table_cell_separators = ["|", "/", ","]
for separator in table_cell_separators:
    value = pypar.Combine(
        word_token_regex(separator) * (0, 10),
        joinString=' ',
        adjacent=False)
    value.setParseAction(lambda start, tokens: (start, tokens[0]))
    empty = pypar.Empty()
    empty.setParseAction(lambda start, tokens: (start, tokens))
    value = pypar.Group(value + empty)
    row = pypar.Group(pypar.Optional(separator).suppress() +
                      (value + pypar.Literal(separator).suppress()) * (1, None) +
                      pypar.Optional(value) +
                      (pypar.StringEnd() | pypar.Literal("\n")).suppress() +
                      pypar.Optional("\n").suppress())
    table_parser ^= (
        (pypar.LineStart() + pypar.Optional(pypar.White())).suppress() +
        row * (1, None)).setResultsName("delimiter:" + separator)
예제 #7
0
    def __init__(self, extra_literals=[]):
        """
        expop   :: '^'
        multop  :: '*' | '/'
        addop   :: '+' | '-'
        integer :: ['+' | '-'] '0'..'9'+
        atom    :: PI | E | real | fn '(' expr ')' | '(' expr ')'
        factor  :: atom [ expop factor ]*
        term    :: factor [ multop factor ]*
        expr    :: term [ addop term ]*
        """
        point = pp.Literal(".")
        e = pp.CaselessLiteral("E")
        fnumber = pp.Combine(pp.Word("+-" + pp.nums, pp.nums) +
                             pp.Optional(point + pp.Optional(pp.Word(pp.nums))) +
                             pp.Optional(e + pp.Word("+-" + pp.nums, pp.nums)))
        ident = pp.Word(pp.alphas, pp.alphas + pp.nums + "_$")
        plus = pp.Literal("+")
        minus = pp.Literal("-")
        mult = pp.Literal("*")
        div = pp.Literal("/")
        lpar = pp.Literal("(").suppress()
        rpar = pp.Literal(")").suppress()
        addop = plus | minus
        multop = mult | div
        expop = pp.Literal("^")
        pi = pp.CaselessLiteral("PI")

        self.extra_literals = extra_literals
        pp_extra_literals = functools.reduce(operator.or_, [pp.CaselessLiteral(e) for e in extra_literals], pp.NoMatch())

        expr = pp.Forward()
        atom = ((pp.Optional(pp.oneOf("- +")) +
                 (pi | e | pp_extra_literals | fnumber | ident + lpar + expr + rpar).setParseAction(self.pushFirst))
                | pp.Optional(pp.oneOf("- +")) + pp.Group(lpar + expr + rpar)
                ).setParseAction(self.pushUMinus)
        # by defining exponentiation as "atom [ ^ factor ]..." instead of
        # "atom [ ^ atom ]...", we get right-to-left exponents, instead of left-to-right
        # that is, 2^3^2 = 2^(3^2), not (2^3)^2.
        factor = pp.Forward()
        factor << atom + pp.ZeroOrMore((expop + factor).setParseAction(self.pushFirst))
        term = factor + pp.ZeroOrMore((multop + factor).setParseAction(self.pushFirst))
        expr << term + pp.ZeroOrMore((addop + term).setParseAction(self.pushFirst))
        # addop_term = ( addop + term ).setParseAction( self.pushFirst )
        # general_term = term + ZeroOrMore( addop_term ) | OneOrMore( addop_term)
        # expr <<  general_term
        self.bnf = expr
        # map operator symbols to corresponding arithmetic operations
        epsilon = 1e-12
        self.opn = {"+": operator.add,
                    "-": operator.sub,
                    "*": operator.mul,
                    "/": operator.truediv,
                    "^": operator.pow}
        self.fn = {"sin": math.sin,
                   "cos": math.cos,
                   "tan": math.tan,
                   "abs": abs,
                   "trunc": lambda a: int(a),
                   "round": round,
                   "sgn": lambda a: abs(a) > epsilon and pp.cmp(a, 0) or 0}
예제 #8
0
class DockerfileCommand(object):
    parser = p.NoMatch()

    @classmethod
    def parse(cls, value):
        return cls.parser.parseString(value, parseAll=True)
예제 #9
0
 def _compile_impossible(self, element, src_state, dst_state, grammar, kaldi_rule, fst):
     # FIXME: not impossible enough (lower probability?)
     fst.add_arc(src_state, dst_state, self.impossible_word.lower())
     return pp.NoMatch()