def _ReadArithExpr(self, do_next=True): """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. """ if do_next: self._Next(lex_mode_e.ARITH) # calls self.ReadWord(lex_mode_e.ARITH) a_parser = tdop.TdopParser(arith_parse.SPEC, self) anode = a_parser.Parse() if not anode: error_stack = a_parser.Error() self.error_stack.extend(error_stack) return anode # could be None
def MakeArithParser(self, code_str, arena): """ NOTE: We want to add tokens to a different arena, so we don't mess up the translation. """ line_reader = reader.StringLineReader(code_str, arena) line_lexer = lexer.LineLexer(match.MATCHER, '', arena) lx = lexer.Lexer(line_lexer, line_reader) w_parser = word_parse.WordParser(self, lx, line_reader, lex_mode=lex_mode_e.ARITH) a_parser = tdop.TdopParser(arith_parse.SPEC, w_parser) return a_parser