简体   繁体   中英

Use custom functions in Jison

I'm playing around with Jison in order to add a new custom function. Starting with the example at Jison documentation :

{
    "lex": {
        "rules": [
           ["\\s+",                    "/* skip whitespace */"],
           ["[0-9]+(?:\\.[0-9]+)?\\b", "return 'NUMBER';"],
           ["\\*",                     "return '*';"],
           ["\\/",                     "return '/';"],
           ["-",                       "return '-';"],
           ["\\+",                     "return '+';"],
           ["\\^",                     "return '^';"],
           ["\\(",                     "return '(';"],
           ["\\)",                     "return ')';"],
           ["PI\\b",                   "return 'PI';"],
           ["E\\b",                    "return 'E';"],
           ["$",                       "return 'EOF';"]
        ]
    },

    "operators": [
        ["left", "+", "-"],
        ["left", "*", "/"],
        ["left", "^"],
        ["left", "UMINUS"]
    ],

    "bnf": {
        "expressions" :[[ "e EOF",   "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",     "$$ = -$2;", {"prec": "UMINUS"} ],
              [ "( e )",   "$$ = $2;" ],
              [ "NUMBER",  "$$ = Number(yytext);" ],
              [ "E",       "$$ = Math.E;" ],
              [ "PI",      "$$ = Math.PI;" ]]
    }
}

If I add the code of the function in the e array it works:

{
    "lex": {
        "rules": [
           ...
           ['sin', 'return "SIN";'],
        ]
    },

    ...

    "bnf": {
         ...    
        "e" :[...,
              ['SIN ( e )', '$$ = Math.sin($3)']]
    }
}

However, trying to add it as a custom function, it fails:

function mySin(x) {
   return Math.sin(x);
}

{
    "lex": {
        "rules": [
           ...
           ['sin', 'return "SIN";'],
        ]
    },

    ...

    "bnf": {
         ...    
        "e" :[...,
              ['SIN ( e )', '$$ = mySin($3)']]
    }
}

I'm new to Jison, so maybe I'm doing something wrong. I have tried to find the solution in the documentation and existing questions, but I failed.

Any hint is welcome!

I'm hitting a similar problem with jison running in the nodejs/CommonJS mode. My issue is that the parser is running in the global scope, so I found if I define my functions with syntax global.myFunction = function(x) {} then they should be referenced OK from the actions of the parser. Bit of a hack I think, I'm sure someone else might have a more elegant solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM