3.2. SQL Subset Defined by EBNF

In order to create the subset of SQL I desired I first had to define it. EBNF notation is used to formally specify the syntax and grammar of a language and was the obvious choice for this task. Correctly defining the language at the start of the process meant that I knew exactly what the syntactical structure of CsvSQL was to be from the outset.


command ::= define_data
    | modify_data
    | system_command

define_data ::= create_command 

modify_data ::= select_command
    | insert_command
    | update_command
    | delete_command

system_command ::=
    | describe_command
    |	open_command
    | close_command
    | save_command
    | list_command
    | clear_command
    | dump_command
    | help_command

create_command ::=
    ( "CREATE" | "create" ) (character_set)+ 
    "("((character_set)+,)+")" 
    ("WITH"|"with") ("VALUES"|"values") 
    "("((character_set)+,)+")" 

select_command ::= 
    ("SELECT"|"select")  
    ("*"|(character_set)+) 
    ("FROM"|"from") 
    (character_set)+ 
    [("WHERE"|"where") condition]
    [("LIMIT"|"limit") (numeric)+]

insert_command ::= 
    ( "INSERT" | "insert" ) 
    ("INTO"|"into") 
    (character_set)+ 
    "("((character_set)+,)+")" 
    ("VALUES"|"values") 
    "("((character_set)+,)+")" 

update_command ::= 
    ("UPDATE"|update")
    (character_set)+ 
    ("SET"|"set")
    (character_set)+ 
    "="
    (character_set)+ 
    [("WHERE"|"where") condition]

delete_command ::= 
    ("DELETE"|"delete")
    ("FROM"|"from")
    (character_set)+ 
    [("WHERE"|"where") condition]

open_command ::=
    ("OPEN"|"open")
    (character_set)+ 

close_command ::=
    ("CLOSE"|"close")
    (character_set)+ 

save_command ::= 
    ("SAVE"|"save")
    | ("SAVE"|"save")
      ("AS"|"as")
      (character_set)+ 

list ::=
    ("LS"|"ls"|"DIR"|"dir")
    | ("LS"|"ls"|"DIR"|"dir")
      (character_set)+

clear ::=
    ("CLEAR"|"clear"|"CLS"|"cls")

dump ::= 
    ("DUMP"|"dump")

help ::=
    ("help"|"HELP"|"/HELP"|"/help"|"/?")

condition ::= 
    (character_set)+
    (["<"|">"|"!"]=|["<"|">"|"="])
    (character_set)+
    [(("AND"|"and")|("OR"|"or"))
    (character_set)+
    (["<"|">"|"!"]=|["<"|">"|"="])
    (character_set)+]

character_set ::= 
    "a"|"b"|"c"|"d"|"e"|"f"|"g"|"h"|"i"|"j"|"k"|"l"|"m"
    "n"|"o"|"p"|"q"|"r"|"s"|"t"|"u"|"v"|"w"|"x"|"y"|"z"
    |"A"|"B"|"C"|"D"|"E"|"F"|"G"|"H"|"I"|"J"|"K"|"L"|"M"
    |"N"|"O"|"P"|"Q"|"R"|"S"|"T"|"U"|"V"|"W"|"X"|"Y"|"Z"
    |"0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
    |"-"|"_"|"("|")"|"."|","|"""|"/"|"\"|"@"|"#"|"~"|"|"
    |"*"|"&"|"%"|"$"|"£"|"!"|"+"|"?"|">"|"<"|"="

numeric ::= 
    "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"