增广抽象语法树

时间:2016-03-01 19:55:09

标签: abstract-syntax-tree grako

这是一个简单的语法:

START = DECL DECL $ ;
DECL = TYPE NAME '=' VAL ;
TYPE = 'int' | 'float' ;
NAME = 'a' | 'b' ;
VAL = '4' ;

我使用Grako解析此输入流:

int a = 4
float b = 4

我检索这个抽象语法树(JSON):

[
  "int",
  "a",
  [
    "=",
    "4"
  ],
  [
    "float",
    "b",
    [
      "=",
      "4"
    ]
  ]
]

有没有一种简单的方法可以获得这样的AST:

[
  "int" TYPE,
  "a" NAME,
  [
    "=" DECL,
    "4" VAL
  ],
  [
    "float" TYPE,
    "b" NAME,
    [
      "=" DECL,
      "4" VAL
    ]
  ]
]

或者这个:

...
"int TYPE",
...

我相信Grako生成的解析器中的语义动作是解决方案,但我无法弄明白。

有一种简单的方法吗?

1 个答案:

答案 0 :(得分:2)

您建议的输出格式不是JSON兼容的,它不是Python。通过使用Grako的AST自定义功能,您可以获得可以在Python和任何其他具有JSON库的语言中处理的输出。

通过向感兴趣的元素添加AST名称来修改语法,如下所示:

START = DECL DECL $ ;
DECL = TYPE:TYPE NAME:NAME '=' VAL:VAL ;
TYPE = 'int' | 'float' ;
NAME = 'a' | 'b' ;
VAL = '4' ;

你将获得这样的输出:

AST:
[AST({'NAME': 'a', 'VAL': '4', 'TYPE': 'int'}), AST({'NAME': 'b', 'VAL': '4', 'TYPE': 'float'})]

JSON:
[
  {
    "TYPE": "int",
    "NAME": "a",
    "VAL": "4"
  },
  {
    "TYPE": "float",
    "NAME": "b",
    "VAL": "4"
  }
]

生成的AST很容易处理成您需要的最终输出。