[javascript]spreadsheet4 EBNF imports,exports

一度にマクロまで拡張すると修正が多そうなので、一旦、数式と値にEBNFを分割し、数式のEBNFから値のEBNFの(非)終端記号を参照できる様な仕組み(imports,exports)を作ってみた。

(*$ SEQUENCE SEPARATOR IS NOT REQUIRED $*)
(*$ export {value_cell,time_stamp,date,number,boolean,sqstring as singleQuoteString,text} from "CELL_VALUE"  $*)
(* セルのデータ *)
value_cell          = time_stamp | date | time | number | boolean | sqstring | text ;
time_stamp          = date ' ' time ;
date                = yyyy '/' MM '/' dd  | MM '/' dd ;
yyyy                = /\\d{4}/ ;
MM                  = /\\d{1,2}/ ;
dd                  = /\\d{1,2}/ ;
time                = HH ':' mm ':' ss | HH ':' mm  ;
HH                  = /\\d{1,2}/ ;
mm                  = /\\d{1,2}/ ;
ss                  = /\\d{1,2}/ ;
number              = /[-]?([0-9]+)([.][0-9]*)?/ ;
boolean             = /true/i | /false/i ;
sqstring            = /'.*/ ;
text                = /.+/ ;
(*$ SEQUENCE SEPARATOR IS NOT REQUIRED $*)
(*$ export expr from "EXPR" $*)
(*$ import defaultExport from "CELL_VALUE" $*)
(* セルのデータ *)
cell                = expr_cell | value_cell ;
(* 数式 *)
expr_cell           = '=' expr ;
expr                = logical_expr ;
logical_expr        = add_sub_expr [ ( '=' | '>' | '<' | '>=' | '<=' | '<>' ) add_sub_expr ] ;
add_sub_expr        = mul_div_expr { ( '+' | '-' | '&' ) mul_div_expr } ;
mul_div_expr        = factor { ( '*' | '/' ) factor } ;
factor              = value | parenthesis_expr ;
parenthesis_expr    = '(' expr ')' ;
value               = number | boolean | function_def | a1_range | a1 | dqstring ;
a1_range            = a1 ':' a1 ;
a1                  = /([A-Za-z]+[1-9][0-9]*)/ ;
dqstring            = /"[^"]*"/ ;
function_def        = symbol '(' parameters ')' ;
symbol              = /([A-Za-z][A-Za-z0-9_]*)/ ;
parameters          = [ expr ] { ',' expr } ;

node.jsのimportを参考にこんな感じになっている。

名前付き import: (*$ import { export1, export2 } from "module-name" $*)
デフォルトの import: (*$ import defaultExport from "module-name" $*)

こうすることで、

(*$ export {value_cell,time_stamp,date,number,boolean,sqstring as singleQuoteString,text} from "CELL_VALUE" $*)

値EBNF側で、{非}終端記号をindexedDBに書き込むtype名でexportする様にすれば、

(*$ import defaultExport from "CELL_VALUE" $*)

importする側はdefaultExportだけで済む。

テキストをガリガリしないでEBNFなimportParserとexportParserクラスを追加し、なんとか最低限の文法(上の2つダケ)を実装した。

(*$ SEQUENCE SEPARATOR IS NOT REQUIRED $*)
(* EXPORT *)
exportSyntax        = "export" members "from" ebnf_export_name;
members             = member | "{" member { "," member } "}" ;
member              = symbol { "as" alias } ;
alias               = symbol;
ebnf_export_name    = dqstring;
dqstring            = /"[^"]*"/ ;
symbol              = /([A-Za-z][A-Za-z0-9_]*)/ ;
(*$ SEQUENCE SEPARATOR IS NOT REQUIRED $*)
(* IMPORT *)
importSyntax        = "import" ( defaultExport | members ) "from" ebnf_export_name ;
defaultExport       = "defaultExport" ;
members             = member | "{" member { "," member } "}" ;
member              = symbol { "as" alias } ;
alias               = symbol;
ebnf_export_name    = dqstring;
dqstring            = /"[^"]*"/ ;
symbol              = /([A-Za-z][A-Za-z0-9_]*)/ ;

これらのEBNFをパースする時点ではまだimportもexportも未登録状態なので、各自がexport処理し、ebnfParserのparseの中で直接importとexportをimportさせた。

当初はebnfParser.#parse内でEBNFテキスト中のexportを処理させたが、cell_valueやcell_exprのパーサのマップを反映する前にimportしてしまったので計算するデータが全て文字になっていたから、各クラスで#makeParser後にebnfParser.exportメソッドを呼びださせた。

後、できるだけ、return [……] や {……} を、return new xxxx(….) に書換え。

なんでもEBNF化すれば良い訳ではないけれど、これに限ってはトコトンEBNF化しないと・・・




コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA