Javascript 向JISON添加声明
我这里有一个JISON计算器示例的稍微修改版本:Javascript 向JISON添加声明,javascript,parsing,parser-generator,jison,Javascript,Parsing,Parser Generator,Jison,我这里有一个JISON计算器示例的稍微修改版本: /* description: Parses end executes mathematical expressions. */ /* lexical grammar */ %lex %% \s+ /* skip whitespace */ [0-9]+("."[0-9]+)?\b return 'NUMBER' "*" return '*' "/"
/* description: Parses end executes mathematical expressions. */
/* lexical grammar */
%lex
%%
\s+ /* skip whitespace */
[0-9]+("."[0-9]+)?\b return 'NUMBER'
"*" return '*'
"/" return '/'
"-" return '-'
"+" return '+'
"^" return '^'
"!" return '!'
"%" return '%'
"(" return '('
")" return ')'
"PI" return 'PI'
"E" return 'E'
<<EOF>> return 'EOF'
. return 'INVALID'
/lex
/* operator associations and precedence */
%left '+' '-'
%left '*' '/'
%left '^'
%right '!'
%right '%'
%left UMINUS
%start expressions
%% /* language grammar */
expressions
: e EOF
{ typeof console !== 'undefined' ? console.log($1) : print($1);
return $1; }
;
e
: e '+' e
{$$ = $1+$3;}
| e '-' e
{$$ = $1-$3;}
| e '*' e
{$$ = $1*$3;}
| e '/' e
{$$ = $1/$3;}
| e '^' e
{$$ = Math.pow($1, $3);}
| e '!'
{{
$$ = fact($1);
}}
| e '%'
{$$ = $1/100;}
| '-' e %prec UMINUS
{$$ = -$2;}
| '(' e ')'
{$$ = $2;}
| NUMBER
{$$ = Number(yytext);}
| E
{$$ = Math.E;}
| PI
{$$ = Math.PI;}
;
%%
/*why doesn't this work at runtime?
I see other examples defining declarations this way but I must be doing something wrong
I couldn't find a syntactically valid way of putting this declaration anywhere but here,
which is probably the issue*/
function fact(n) {
var tot=1;
for(var i=2;i<=n;++i) {
tot*=i;
}
return tot;
}
/*说明:解析并执行数学表达式*/
/*词汇语法*/
%莱克斯
%%
\s+/*跳过空格*/
[0-9]+(“[0-9]+)?\b返回“编号”
“*”返回“*”
“/”返回“/”
“-“返回”-”
“+”返回“+”
“^”返回“^”
“!“返回”!”
“%”返回“%”
“(”返回“(”
“返回”)
“PI”返回“PI”
“E”返回“E”
返回“EOF”
. 返回“无效”
/莱克斯
/*运算符关联和优先级*/
%左'+''-'
%左'*''/'
%左“^”
%对‘!’
%对“%”
%左耳门
%起始表达式
%%/*语言语法*/
表达
:e EOF
{typeof console!='undefined'?console.log($1):print($1);
返回$1;}
;
E
:e'+'e
{$$ = $1+$3;}
|e'-'e
{$$ = $1-$3;}
|e'*'e
{$$ = $1*$3;}
|e'/'e
{$$ = $1/$3;}
|"^"e
{$$=Math.pow($1,$3);}
|e'!'
{{
$$=事实(1美元);
}}
|e“%”
{$$ = $1/100;}
|“-”e%前白蛋白
{$$ = -$2;}
|“(‘e’)”
{$$ = $2;}
|数
{$$=Number(yytext);}
|E
{$$=Math.E;}
|圆周率
{$$=Math.PI;}
;
%%
/*为什么这在运行时不起作用?
我看到了其他这样定义声明的例子,但我一定是做错了什么
我找不到一个语法上有效的方法把这个声明放在这里以外的任何地方,
这可能就是问题所在*/
函数事实(n){
var-tot=1;
对于(var i=2;i调用在您的产品中定义的函数(例如fact
),您可以使用mod brace表示法%{
和%}
进行多行语义操作:
e
: e '+' e
...
| e '!'
%{
// the %{ tells jison this is a multi-line js eval statement
$$ = fact($1);
%}
;
作为最终解决方案,请尝试以下方法:
/* lexical grammar */
%lex
%%
\s+ /* skip whitespace */
[0-9]+("."[0-9]+)?\b return 'NUMBER'
"*" return '*'
"/" return '/'
"-" return '-'
"+" return '+'
"^" return '^'
"!" return '!'
"%" return '%'
"(" return '('
")" return ')'
"PI" return 'PI'
"E" return 'E'
<<EOF>> return 'EOF'
. return 'INVALID'
/lex
/* operator associations and precedence */
%left '+' '-'
%left '*' '/'
%left '^'
%right '!'
%right '%'
%left UMINUS
%start expressions
%% /* language grammar */
expressions
: e EOF
%{
typeof console !== 'undefined' ? console.log($1) : print($1);
return $1;
%}
;
e
: e '+' e
{$$ = $1+$3;}
| e '-' e
{$$ = $1-$3;}
| e '*' e
{$$ = $1*$3;}
| e '/' e
{$$ = $1/$3;}
| e '^' e
{$$ = Math.pow($1, $3);}
| e '!'
%{
$$ = fact($1);
%}
| e '%'
{$$ = $1/100;}
| '-' e %prec UMINUS
{$$ = -$2;}
| '(' e ')'
{$$ = $2;}
| NUMBER
{$$ = Number(yytext);}
| E
{$$ = Math.E;}
| PI
{$$ = Math.PI;}
;
%%
function fact(n) {
var tot=1;
for(var i=2;i<=n;++i) {
tot*=i;
}
return tot;
}
/*词汇语法*/
%莱克斯
%%
\s+/*跳过空格*/
[0-9]+(“[0-9]+)?\b返回“编号”
“*”返回“*”
“/”返回“/”
“-“返回”-”
“+”返回“+”
“^”返回“^”
“!“返回”!”
“%”返回“%”
“(”返回“(”
“返回”)
“PI”返回“PI”
“E”返回“E”
返回“EOF”
.返回“无效”
/莱克斯
/*运算符关联和优先级*/
%左'+''-'
%左'*''/'
%左“^”
%对‘!’
%对“%”
%左耳门
%起始表达式
%%/*语言语法*/
表达
:e EOF
%{
控制台类型!=“未定义”?console.log($1):打印($1);
退还$1;
%}
;
E
:e'+'e
{$$ = $1+$3;}
|e'-'e
{$$ = $1-$3;}
|e'*'e
{$$ = $1*$3;}
|e'/'e
{$$ = $1/$3;}
|"^"e
{$$=Math.pow($1,$3);}
|e'!'
%{
$$=事实(1美元);
%}
|e“%”
{$$ = $1/100;}
|“-”e%前白蛋白
{$$ = -$2;}
|“(‘e’)”
{$$ = $2;}
|数
{$$=Number(yytext);}
|E
{$$=Math.E;}
|圆周率
{$$=Math.PI;}
;
%%
函数事实(n){
var-tot=1;
对于@Nucleon和@chaosbohne所指出的(var i=2;i),公认的答案是不正确的
直接来自Jison wiki()
在lexer actions中,如果要使用块样式语句,请使用%{…%}分隔符,例如:
.* %{
if (true) {
console.log('test');
}
// ...
%}
在解析器操作中出于相同目的使用{{..}}分隔符
因此,如果您在lexer中,对于多行操作,请使用%{action%}
。在解析器中,对于多行操作,请使用{{action}
。如果您正在编写单行操作,请使用单大括号{}
在lexer和parser中可以很好地工作。这个解决方案实际上不起作用。如果你将完整的语法复制并粘贴到Jison中,并尝试解析2!
它会给你提供事实没有定义。我正在努力解决这个问题,因为似乎没有关于这个功能的文档。@Nucleon也有同样的问题em并发现它在jison的在线工具中不起作用,但在node.js环境中起作用。也许这些信息对您有帮助!不幸的是,您提到没有找到任何文档…@Nucleon和@chaosbohne,请参见下面的我的答案——自接受原始答案以来,jison的API已更改。多行词法操作由{%}
分隔,而多行解析器操作(问题中引用的操作)由{{}
分隔