idank / bashlex

Python parser for bash
GNU General Public License v3.0
556 stars 94 forks source link

Command substitution #50

Open sereysethy opened 5 years ago

sereysethy commented 5 years ago

Hi, I was about to make a pull request for a command substitution that returned a wrong position when there are spaces in the commands in the command substitution $(foo ). But then I discovered another problem and I couldnt find how to fix it. It is when there is a semi column in the list of commands, parsing failed.

Ex: parsing this command failed $(foo;). I got this error. Can you tell me where the problem lies? It is a list, but I couldnt find where to fix it. It does not happen with another form of command subsitution `command;`. I know they are treated differently in parser.

File "python3.6/site-packages/bashlex/parser.py", line 605, in parse
        parts = [p.parse()]
      File "python3.6/site-packages/bashlex/parser.py", line 686, in parse
        tree = theparser.parse(lexer=self.tok, context=self)
      File "python3.6/site-packages/bashlex/yacc.py", line 277, in parse
        return self.parseopt_notrack(input,lexer,debug,tracking,tokenfunc,context)
      File "python3.6/site-packages/bashlex/yacc.py", line 998, in parseopt_notrack
        p.callable(pslice)
      File "python3.6/site-packages/bashlex/parser.py", line 157, in p_simple_command_element
        p[0] = [_expandword(parserobj, p.slice[1])]
      File "python3.6/site-packages/bashlex/parser.py", line 137, in _expandword
        doublequoted, 0, 0)
      File "python3.6/site-packages/bashlex/subst.py", line 271, in _expandwordinternal
        node, sindex[0] = _paramexpand(parserobj, string, sindex[0])
      File "python3.6/site-packages/bashlex/subst.py", line 165, in _paramexpand
        return _extractcommandsubst(parserobj, string, zindex + 1)
      File "python3.6/site-packages/bashlex/subst.py", line 55, in _extractcommandsubst
        node, si = _parsedolparen(parserobj, string, sindex)
      File "python3.6/site-packages/bashlex/subst.py", line 42, in _parsedolparen
        node, endp = _recursiveparse(parserobj, base, sindex, tokenizerargs)
      File "python3.6/site-packages/bashlex/subst.py", line 23, in _recursiveparse
        node = p.parse()
      File "python3.6/site-packages/bashlex/parser.py", line 686, in parse
        tree = theparser.parse(lexer=self.tok, context=self)
      File "python3.6/site-packages/bashlex/yacc.py", line 277, in parse
        return self.parseopt_notrack(input,lexer,debug,tracking,tokenfunc,context)
      File "python3.6/site-packages/bashlex/yacc.py", line 1079, in parseopt_notrack
        tok = self.errorfunc(errtoken)
      File "python3.6/site-packages/bashlex/parser.py", line 543, in p_error
        p.lexer.source, p.lexpos)
    bashlex.errors.ParsingError: unexpected token ')' (position 4)
idank commented 5 years ago

Command substitutions are parsed recursively. The code that handles this is in bashlex/subst.py, see _recursiveparse. I'd try debugging it and putting a breakpoint in that function.