idank / bashlex

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

Elif clause #48

Closed sereysethy closed 5 years ago

sereysethy commented 5 years ago

I proposed a fix for elif clause when there more than 2 elif clauses. Here is the problem, considering if else clause below:

if [ -f /cond1 ];
then
  cmd1;
elif [ -f /cond2 ];
then
  cmd2;
elif [ -f /cond3 ];
then
 cmd3;
else
 cmd4;
fi

Parsed result before fix, elif clause is wrongly added as word because it was list not a node:

CompoundNode(list=[
  IfNode(pos=(0, 104), parts=[
    ReservedwordNode(pos=(0, 2), word='if'),
    ListNode(pos=(3, 17), parts=[
        CommandNode(pos=(3, 16), parts=[
          WordNode(pos=(3, 4), word='['),
          WordNode(pos=(5, 7), word='-f'),
          WordNode(pos=(8, 14), word='/cond1'),
          WordNode(pos=(15, 16), word=']'),
        ]),
        OperatorNode(op=';', pos=(16, 17)),
      ]),
    ReservedwordNode(pos=(18, 22), word='then'),
    ListNode(pos=(23, 28), parts=[
        CommandNode(pos=(23, 27), parts=[
          WordNode(pos=(23, 27), word='cmd1'),
        ]),
        OperatorNode(op=';', pos=(27, 28)),
      ]),
    ReservedwordNode(pos=(29, 33), word='elif'),
    ListNode(pos=(34, 48), parts=[
        CommandNode(pos=(34, 47), parts=[
          WordNode(pos=(34, 35), word='['),
          WordNode(pos=(36, 38), word='-f'),
          WordNode(pos=(39, 45), word='/cond2'),
          WordNode(pos=(46, 47), word=']'),
        ]),
        OperatorNode(op=';', pos=(47, 48)),
      ]),
    ReservedwordNode(pos=(49, 53), word='then'),
    ListNode(pos=(54, 59), parts=[
        CommandNode(pos=(54, 58), parts=[
          WordNode(pos=(54, 58), word='cmd2'),
        ]),
        OperatorNode(op=';', pos=(58, 59)),
      ]),
    ReservedwordNode(pos=(0, 0), word=[
      ReservedwordNode(pos=(60, 64), word='elif'),
      ListNode(pos=(65, 79), parts=[
          CommandNode(pos=(65, 78), parts=[
            WordNode(pos=(65, 66), word='['),
            WordNode(pos=(67, 69), word='-f'),
            WordNode(pos=(70, 76), word='/cond3'),
            WordNode(pos=(77, 78), word=']'),
          ]),
          OperatorNode(op=';', pos=(78, 79)),
        ]),
      ReservedwordNode(pos=(80, 84), word='then'),
      ListNode(pos=(85, 90), parts=[
          CommandNode(pos=(85, 89), parts=[
            WordNode(pos=(85, 89), word='cmd3'),
          ]),
          OperatorNode(op=';', pos=(89, 90)),
        ]),
      ReservedwordNode(pos=(91, 95), word='else'),
      ListNode(pos=(96, 101), parts=[
          CommandNode(pos=(96, 100), parts=[
            WordNode(pos=(96, 100), word='cmd4'),
          ]),
          OperatorNode(op=';', pos=(100, 101)),
        ]),
    ]),
    ReservedwordNode(pos=(102, 104), word='fi'),
  ]),
], pos=(0, 104))

Parsed result after fix. The fix is to extend parts rather creating a new ReservedWord.

CompoundNode(list=[
  IfNode(pos=(0, 104), parts=[
    ReservedwordNode(pos=(0, 2), word='if'),
    ListNode(pos=(3, 17), parts=[
        CommandNode(pos=(3, 16), parts=[
          WordNode(pos=(3, 4), word='['),
          WordNode(pos=(5, 7), word='-f'),
          WordNode(pos=(8, 14), word='/cond1'),
          WordNode(pos=(15, 16), word=']'),
        ]),
        OperatorNode(op=';', pos=(16, 17)),
      ]),
    ReservedwordNode(pos=(18, 22), word='then'),
    ListNode(pos=(23, 28), parts=[
        CommandNode(pos=(23, 27), parts=[
          WordNode(pos=(23, 27), word='cmd1'),
        ]),
        OperatorNode(op=';', pos=(27, 28)),
      ]),
    ReservedwordNode(pos=(29, 33), word='elif'),
    ListNode(pos=(34, 48), parts=[
        CommandNode(pos=(34, 47), parts=[
          WordNode(pos=(34, 35), word='['),
          WordNode(pos=(36, 38), word='-f'),
          WordNode(pos=(39, 45), word='/cond2'),
          WordNode(pos=(46, 47), word=']'),
        ]),
        OperatorNode(op=';', pos=(47, 48)),
      ]),
    ReservedwordNode(pos=(49, 53), word='then'),
    ListNode(pos=(54, 59), parts=[
        CommandNode(pos=(54, 58), parts=[
          WordNode(pos=(54, 58), word='cmd2'),
        ]),
        OperatorNode(op=';', pos=(58, 59)),
      ]),
    ReservedwordNode(pos=(60, 64), word='elif'),
    ListNode(pos=(65, 79), parts=[
        CommandNode(pos=(65, 78), parts=[
          WordNode(pos=(65, 66), word='['),
          WordNode(pos=(67, 69), word='-f'),
          WordNode(pos=(70, 76), word='/cond3'),
          WordNode(pos=(77, 78), word=']'),
        ]),
        OperatorNode(op=';', pos=(78, 79)),
      ]),
    ReservedwordNode(pos=(80, 84), word='then'),
    ListNode(pos=(85, 90), parts=[
        CommandNode(pos=(85, 89), parts=[
          WordNode(pos=(85, 89), word='cmd3'),
        ]),
        OperatorNode(op=';', pos=(89, 90)),
      ]),
    ReservedwordNode(pos=(91, 95), word='else'),
    ListNode(pos=(96, 101), parts=[
        CommandNode(pos=(96, 100), parts=[
          WordNode(pos=(96, 100), word='cmd4'),
        ]),
        OperatorNode(op=';', pos=(100, 101)),
      ]),
    ReservedwordNode(pos=(102, 104), word='fi'),
  ]),
], pos=(0, 104))
idank commented 5 years ago

Hi, this looks like a good bug fix, thanks!

Can you separate the changes in this branch to only be about the bug fix? Also please add a test if possible.

sereysethy commented 5 years ago

I created a new branch for bug fix. Please check.