2

像这样定义块

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); }

想要实现 {float a =3;a*3+1;} return 10 我不知道如何在“decl”和“exp_stat”这两个语句中引用 id。谁能分享一个例子?

4

1 回答 1

1

简短的回答是您需要定义、实习并最终引用您声明的变量。

所以当你说:'int a=1;'时,你想把这个值保存(实习生)到某个地方,这样你就可以在其他地方需要它时检索它。

对我们来说幸运的是,pegjs它支持“全局”代码部分,您可以在其中完全做到这一点,例如:

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

然后,当您的解析器识别出有效的声明时,您:

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
 */

最后,当您需要该值时,您可以识别表达式中的符号并在评估表达式时进行替换。

有关完整的工作示例,请参阅此要点,它为您的语言规范提供了一个完全工作的解析器。

于 2017-01-26T20:40:55.053 回答