私は最近 Jison を試していて、いくつかの数式を (少なくとも部分的に) 解析できる文法を作成しようと考えました。
しかし、今では、フォームの乗算を許可するルールを作成する方法について混乱しています7a
(たとえば) wherea
は以前に定義された変数です。コードでこれを実行しようとしましたが、 と の間にadjmul
スペースがないとパーサーは機能しません。要するに、プログラム内で数値と変数が隣接している場合、それらの間の乗算を許可するルール/ルールを作成するにはどうすればよいですか?7
a
私は一般的に Jison のようなパーサーに慣れていないので、現在のルールを簡素化する方法があるかどうかも知りたいです。
コード:
/* description: Parses math files. */
/* lexical grammar */
%lex
%%
[\n;] {return 'NL';}
\s+ {/* skip whitespace */}
"=" {return '=';}
[0-9]+("."[0-9]+)?\b {return 'NUMBER';}
"*" {return '*';}
"/" {return '/';}
"-" {return '-';}
"+" {return '+';}
"^" {return '^';}
"(" {return '(';}
")" {return ')';}
[a-zA-Z]+ {return 'ID';}
"," {return ',';}
"|" {return '|';}
"!" {return '!';}
<<EOF>> {return 'EOF';}
/lex
/* operator associations and precedence */
%left '|'
%left ','
%left '+' '-'
%left '*' '/'
%left '^'
%left UMINUS
%left '!'
%start program
%% /* language grammar */
program
: statement 'NL' program
{$$ = "";}
| statement EOF
{$$ = "";}
;
statement
: e
{$$ = $1;}
| ID '=' e
{identifiers[$1] = $3;}
;
e
: block '+' block
{$$ = $1 + $3;}
| block '-' block
{$$ = $1 - $3;}
| block '*' block
{$$ = $1 * $3;}
| block '/' block
{$$ = $1 / $3;}
| block '^' block
{$$ = Math.pow($1, $3);}
| '-' block %prec UMINUS
{$$ = -$2;}
| block '!'
{$$ = util.factorial($1);}
| ID '(' csv ')'
{$$ = identifiers[$1].apply(null, $3);}
| ID '(' ')'
{$$ = identifiers[$1]();}
| ID
{$$ = identifiers[$1];}
| adjmul
| block
;
block
: term
| NUMBER
{$$ = Number(yytext);}
;
term
: '(' e ')'
{$$ = $2;}
;
adjmul
: block term
{$$ = $1 * $2;}
| block ID
{$$ = $1 * identifiers[$2];}
;