예제 #1
0
  def _ReadArithExpr(self):
    # type: () -> arith_expr_t
    """Read and parse an arithmetic expression in various contexts.

    $(( 1+2 ))
    (( a=1+2 ))
    ${a[ 1+2 ]}
    ${a : 1+2 : 1+2}

    See tests/arith-context.test.sh for ambiguous cases.

    ${a[a[0]]} is valid  # VS_RBRACKET vs Id.Arith_RBracket

    ${s : a<b?0:1 : 1}  # VS_COLON vs Id.Arith_Colon

    TODO: Instead of having an eof_type.  I think we should use just run the
    arith parser until it's done.  That will take care of both : and ].  We
    switch the state back.

    See the assertion in ArithParser.Parse() -- unexpected extra input.
    """
    # calls self.ReadWord(lex_mode_e.Arith)
    a_parser = tdop.TdopParser(arith_parse.Spec(), self, self.parse_opts)
    anode = a_parser.Parse()
    return anode
예제 #2
0
 def MakeArithParser(self, code_str):
   # type: (str) -> TdopParser
   """Used for a[x+1]=foo in the CommandParser."""
   line_reader = reader.StringLineReader(code_str, self.arena)
   lx = self._MakeLexer(line_reader)
   w_parser = word_parse.WordParser(self, lx, line_reader)
   w_parser.Init(lex_mode_e.Arith)  # Special initialization
   a_parser = tdop.TdopParser(arith_parse.Spec(), w_parser, self.parse_opts)
   return a_parser
예제 #3
0
def main(argv):
    spec = arith_parse.Spec()

    print("""\
#include "osh_arith_parse.h"

using syntax_asdl::arith_expr_t;
using syntax_asdl::word_t;
using tdop::TdopParser;
""")

    to_declare = collections.defaultdict(set)

    for row in spec.nud_lookup.itervalues():
        mod_name, func_name = row.ModuleAndFuncName()
        to_declare[mod_name].add(('N', func_name))

    log('')
    log('')

    # TODO: namespace are arith_parse or tdop
    for row in spec.led_lookup.itervalues():
        mod_name, func_name = row.ModuleAndFuncName()
        to_declare[mod_name].add(('L', func_name))

    # main program has no headers, so here are prototypes
    for mod_name in to_declare:
        print('namespace %s { ' % mod_name)
        for typ, func in sorted(to_declare[mod_name]):
            if typ == 'N':
                # tdop::NullFunc
                fmt = 'arith_expr_t* %s(TdopParser*, word_t*, int);'
            else:
                # tdop::LeftFunc
                fmt = 'arith_expr_t* %s(TdopParser*, word_t*, arith_expr_t*, int);'
            print(fmt % func)

        print('}')
        print('')

    print("""\
namespace arith_parse {

tdop::LeftInfo kLeftLookup[] = {
  { nullptr, 0, 0 },  // empty
""",
          end='')

    n = max(spec.led_lookup)
    m = max(spec.nud_lookup)
    assert n == m
    log('arith_parse_gen.py: precedence table has %d entries', n)

    for i in xrange(1, n):
        row = spec.led_lookup.get(i)
        if row is None:
            assert False, 'No empty rows anymore'
            print('  { nullptr, 0, 0 },  // empty')
        else:
            print('  %s' % row)

    print("""\
};

tdop::NullInfo kNullLookup[] = {
  { nullptr, 0 },  // empty
""",
          end='')

    for i in xrange(1, n):
        row = spec.nud_lookup.get(i)
        if row is None:
            assert False, 'No empty rows anymore'
            print('  { nullptr, 0 },  // empty')
        else:
            print('  %s' % row)

    print("""\
};

};
""")