grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Some suggestion about the script engine


From: Bean
Subject: Some suggestion about the script engine
Date: Thu, 28 Jun 2007 17:23:23 +0800
User-agent: Mutt/1.5.13 (2006-08-11)

 notice something strange about the script engine:

1. Command is executed as soon as it's parsed, myabe we should wait until the
whole file is analysed.

2. Menu entry is parsed twice.

3. Memory consumption is huge, each token would take up 2048/2096 bytes. Maybe
we should allocate just enough memory to hold the string.

4. Some problem with syntax
For example,

if ls; then ls fi

works (shouldn't be), but

if ls; then ls; fi

doesn't (should be), and

if ls; then
  ls
fi

result in an infinite loop.

I'm thinking about a new architecture. The script can be represented using
binary tree. Every node in the tree has two pointers. Child points to the first
node in the next level, while next points to the next node in the same level.
With this design, when we want to free a certain node, just free its entire
child branch. there is no need to record memory usage anymore.

Here is a sample syntax file.

line: one_line_commands
      {
        $$=$1;
      }
      | function_cmd
      {
        $$=$1;
      }
      | menu_cmd
      {
        $$=$1;
      }

newlines:
          | newlines "\n"

commands: one_line_commands
          {
            $$=$1;
          }
          | one_line_commands "\n" newlines commands
          {
            $$=$1;
            append_items($$, $2);
          }

one_line_commands: command
                {
                  $$=$1;
                  $1->next=0;
                }
                | command ; one_line_commands
                {
                  $$=$1;
                  $1->next=$2;
                }

command: simple_command
         {
           $$=$1;
         }
         | if_command
         {
           $$=$1;
         }


simple_command: text arguments
                {
                   $$->type=SIMPLE_COMMAND;
                   $$->child=$1;
                }

arguments:
          {
            $$=0;
          }
         | text arguments
          {
            $$=$1;
            $1->next=$2;
          }

if_cmdblk: command ;
             {
               $$->type=COMMAND_LIST;
               $$->child=$1;
               $1->next=0;
             }
             || "\n" newlines commands "\n" newlines
             {
               $$->type=COMMAND_LIST;
               $$->child=$2;
             }


if_command: "if" simple_command ; "then" if_cmdblk "fi"
          {
            $$->type=IF_COMMAND;
            $$->child=$2;
            $2->next=$5;
            $5->next=0;
          }
          | "if" simple_command ; "then" if_cmdblk "else" if_cmdblk "fi"
          {
            $$->type=IF_COMMAND;
            $$->child=$2;
            $2->next=$5;
            $5->next=$7;
            $7->next=0;
          }

function_cmd: "function" text newlines "{" newlines commands newlines "}"
              {
                $$->type=FUNCTION_CMD;
                $$->child=$2;
                $2->next->type=COMMAND_LIST;
                $2->next->child=$6;
              }

menu_cmd: "menuentry" text newlines "{" newlines commands newlines "}"
              {
                $$->type=MENU_CMD;
                $$->child=$2;
                $2->next->type=COMMAND_LIST;
                $2->next->child=$6;
              }

Text is the basic token, it can be plain text or text mixed with variable, for
example:

abc
"aa bb"
"aa"bb
aa$BB
aa${BB}cc
...

The lexer would break it into pieces.

abc => abc
"aa bb" => "aa bb"
"aa"bb => "aa" bb
aa$BB => aa $BB
aa${BB}cc => aa $BB cc

When text is evaluated, each piece is evaluated individually, then joined
together to form the end result.

-- 
Bean





reply via email to

[Prev in Thread] Current Thread [Next in Thread]