2

define the block like this

compound_stat
= '{' decl exp_stat '}'

exp_stat
= exp ';'

decl
= decl_specs id ';'

decl_specs
= 'int'/'float'

id
=name:[a-z]+ {return name.join("");}

exp_stat
  = left:multiplicative "+" right:exp_stat { right=right+1;return left + right; }
  / multiplicative

multiplicative
  = left:primary "*" right:multiplicative { return left * right; }
  / primary

primary
  = integer
  /id
  / "(" exp_stat:exp_stat ")" { return exp_stat; }


integer "integer"
  = digits:[0-9]+ { return parseInt(digits.join(""), 10); }

want to achieve that {float a =3;a*3+1;} return 10 i don't know how to reference the id in two statements which are "decl" and "exp_stat". who can share an example?

freyone
  • 349
  • 1
  • 8

1 Answers1

1

The short answer is that you need to define, intern and ultimately reference your declared variables.

So when you say: 'int a=1;', you want to save (intern) that value somewhere so you can retrieve it when you need it elsewhere.

Lucky for us, pegjs supports "global" code sections in which you can do exactly that, as in:

{
  /**
   * Storage of Declared Variables
   * @type {Object}
   */
  const vars = {}
}

Then, when your parser recognizes a valid declaration, you:

vars[id] = { name: id, type: spec, value: val }

/* where id is the name (symbol) of your declared variable: 'a'
   spec is the value of your decl_spec: 'float'
   and val is the value you want to intern
 */

Finally, when you need the value, you recognize the symbol in an expression and do your substitution as you evaluate the expression.

For the full working example, see this gist which provides a fully working parser for your language specification.

Rob Raisch
  • 17,040
  • 4
  • 48
  • 58