Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to parse Variable #379

Open
felixfrtz opened this issue Oct 24, 2018 · 2 comments
Open

How to parse Variable #379

felixfrtz opened this issue Oct 24, 2018 · 2 comments

Comments

@felixfrtz
Copy link

felixfrtz commented Oct 24, 2018

Hey,

I am trying to parse variables within the calculator example. My Code is as follows:

var grammar = {
	"comment": "JSON Math Parser",
	"lex": {
		"rules": [
			["\\s+", "/* skip whitespace */"],
			["[0-9]+(?:\\.[0-9]+)?\\b", "return 'NUMBER'"],
			["\\*", "return '*'"],
			["\\/", "return '/'"],
			["-", "return '-'"],
			["\\+", "return '+'"],
			["\\^", "return '^'"],
			["!", "return '!'"],
			["%", "return '%'"],
			["\\(", "return '('"],
			["\\)", "return ')'"],
			["PI\\b", "return 'PI'"],
			["E\\b", "return 'E'"],
			["$", "return 'EOF'"]
		]
	},

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

	"bnf": {
		"expressions": [["e EOF", "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 !", "$$ = (function(n) {if(n==0) return 1; return arguments.callee(n-1) * n})($1)"],
			["e %", "$$ = $1/100"],
			["- e", "$$ = -$2", { "prec": "UMINUS" }],
			["( e )", "$$ = $2"],
			["NUMBER", "$$ = Number(yytext)"],
			["VARIABLE", "$$ = yy.data[text]"], // this is what I've added
			["E", "$$ = Math.E"],
			["PI", "$$ = Math.PI"]
		]
	}
};

var parser = new Parser(grammar);

var parserSource = parser.generate();
parser.yy = { data: { m: 4 } };
console.log(parser.parse("m")); 

This leads to the following:

Error: Lexical error on line 1. Unrecognized text. m

I used this post to accomplish this, but it isn't working. Any idea what is wrong with the example?

@blackshadev
Copy link

Hi,

Well you don't have a lex rule for variables. The post you mentioned doesn't include this rule, neither does the calculator example.

An example would be:

["\w+", "return 'VARIABLE'"]

You need to define this rule after all your constants and before your EOF rule. It is a but more permissive than required, but it works and it is easy to read.

ps. I can really suggest using a .jison file and use the cmd like (jison grammer.jison) to generate a ,js file instead of creating your own, I find it easier to read, maintain and write. But that is just my opinion.

@AnuragVasanwala
Copy link

Hi @felixfrtz 👋🏻

It is a really old question but I came across this today and would like to share my thoughts.

As per @blackshadev suggestion, it would be good to use .jison and compile ito to generate .js. For your need, you can use official example calculator.jison and add following highlighted lines:

/* description: Parses and 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'
+[a-zA-Z_][a-zA-Z0-9_]*    return 'NAME'
+\'[^\']*\'                return 'STRING'
+\"[^\"]*\"                return 'STRING'
+"TRUE"                    return 'TRUE'
+"true"                    return 'TRUE'
+"FALSE"                   return 'FALSE'
+"false"                   return 'FALSE'
+"NULL"                    return 'NULL'
<<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 '!'
        {{
          $$ = (function fact (n) { return n==0 ? 1 : fact(n-1) * n })($1);
        }}
    | e '%'
        {$$ = $1/100;}
    | '-' e %prec UMINUS
        {$$ = -$2;}
    | '(' e ')'
        {$$ = $2;}
    | NUMBER
        {$$ = Number(yytext);}
+    | NAME
+       { $$ = yy[yytext]; }
+   | STRING
+     {$$ = yytext.substring(1, yytext.length - 1);}
+   | TRUE
+     {$$ = true}
+   | FALSE
+       {$$ = false}
+   | NULL
+       {$$ = null}  
    | E
        {$$ = Math.E;}
    | PI
        {$$ = Math.PI;}
    ;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants