grub-devel
[Top][All Lists]
Advanced

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

Standalone problem to test syntax rules


From: Bean
Subject: Standalone problem to test syntax rules
Date: Wed, 4 Jul 2007 01:53:16 +0800
User-agent: Mutt/1.5.13 (2006-08-11)

Hi,

I have written a small problem to test my parse.y, to compile, use the
following commands:

bison -d -p grub_script_yy -b grub_script parser.y 
gcc -oparser parser.c lexer.c grub_script.tab.c

After compilation, run parser

./parser

Just enter the commands after '##', and the syntax tree associtaed with it
will be displayed.

The program support option - , which is used to disable prompt '##' and '>>'.
This is useful when inputting from files:

./parser - < input_file

Some example:

## aa "aa${BB}cc" "\
>dd"
CMD
  TEXT
    STR  "aa"
  TEXT
    STR  "aa"
    VAR  "BB"
    STR  "cc"
  TEXT
    STR  "dd"

## if aa; then
> bb dd$cc
> fi
IF
  CMDS
    CMD
      TEXT
        STR  "aa"
  CMDS
    CMD
      TEXT
        STR  "bb"
      TEXT
        STR  "dd"
        VAR  "cc"

## function foo {
> set AA=1
> if aa; then bb; else cc; fi
> }
FUNC
  TEXT
    STR  "foo"
  CMDS
    CMD
      TEXT
        STR  "set"
      TEXT
        STR  "AA=1"
    IF
      CMDS
        CMD
          TEXT
            STR  "aa"
      CMDS
        CMD
          TEXT
            STR  "bb"
      CMDS
        CMD
          TEXT
            STR  "cc"

The reason why I like to use binary tree is:

1. Standard data type for all script elements, only one set of function is
needed to manipulate the structure.

2. Enumeration and deallocation is simpler. Instead of using switch, we
can enumerate the tree using its two branch, child and next.

I also figure out how to release memory when syntax error occurs. When a
node is first created using grub_script_newnode, it's added to a linked
list state->free_list. When it's referenced, it's moved from the linked
list to the branch of a tree. If the whole script is parsed, all nodes
will be moved to the final tree, but if it fails at some point, partial
built element can be found in the free list. This way, we can also keep
track of nodes allocated. For example, consider this command:

## aa bb

commands:       command
                {
                  $$=$1;
                }
                | commands command
                {
                  $$=grub_script_catnode(state, $1, $2);
                }

Using the second rule, node bb is moved out of free list and move to the next
branch of aa. Now the free list look like this:

root => 0

free_list => aa => 0
             |
             bb

script:         commands '\n'
                {
                  state->root=grub_script_getnode(state, $1);
                }

Now aa is moved out of free list:

root => aa => 0
        |
        bb

free_list => 0

In any given time, all nodes can be found in either root or free_list.

The latest version of parser support error recovery, for example:

## fi ; aa ; bb ; fi ; ee
syntax error
invalid command
syntax error
invalid command
== TREE BEGIN ==
CMD
  TEXT
    STR  "aa"
CMD
  TEXT
    STR  "bb"
CMD
  TEXT
    STR  "ee"
== TREE END ==

-- 
Bean





reply via email to

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