Python 如何从ANTLR3中的*规则生成列表?
我的语法如下:Python 如何从ANTLR3中的*规则生成列表?,python,parsing,antlr,grammar,antlr3,Python,Parsing,Antlr,Grammar,Antlr3,我的语法如下: grammar Test; options { lang = Python; } declaration returns [value] : 'enum' ID { statement* } { $value = {'id': $ID.text, 'fields': $statement.value} } ; statem
grammar Test;
options {
lang = Python;
}
declaration returns [value]
: 'enum' ID { statement* }
{ $value = {'id': $ID.text,
'fields': $statement.value}
}
;
statement returns [value]
: ID ':' INT ';' { $value = {'id': $ID.text, 'value': int($INT.text)} }
;
要分析类型的语法,请执行以下操作:
enum Test {
Foo: 3;
Bar: 5;
}
然而,我正在努力将语句*规则放入语句列表中。我希望最终解析的对象如下所示:
declaration = {
'id': 'Test',
'fields': [
{'id': 'Foo', 'value': 3},
{'id': 'Bar', 'value': 5},
}
我可以正确解析每个语句
结果,这样每个$statement.value
都是正确的。
但是,考虑到规则声明中语句*
上的星号,有没有一种方法可以轻松地将其压缩为字段列表?我希望有某种语法可以让我免费使用这个选项
现在,它只接受最后一条语句,因此返回:
declaration = {
'id': 'Test',
'fields': [
{'id': 'Bar', 'value': 5},
}
我想要一个通用的解决方案,因为我的语法有很多形式规则:
some_declaration
: keyword ID '{' declaration_statement* '}'
;
注意:我是用Python编写的。
我曾尝试将其编码为一个解析器,后跟一个树语法,但即使最后一个元素是我得到的唯一元素,其余元素也会被丢弃。您可以这样做:
declaration returns [value]
: 'enum' ID
{ $value = {'id': $ID.text,
'fields': []}
}
'{' (r=statement
{ $value['fields'].append($r.value) }
)*
'}'
;
declaration returns [value]
: 'enum' ID
{ $value = {'id': $ID.text,
'fields': []}
}
{ list = $value['fields']
}
'{' statement[list]* '}'
;
statement[list]
: ID ':' INT ';' { $list.append({'id': $ID.text, 'value': int($INT.text)}) }
;
或者,您也可以将字段列表作为参数传递给语句规则,并在其中附加新值。大概是这样的:
declaration returns [value]
: 'enum' ID
{ $value = {'id': $ID.text,
'fields': []}
}
'{' (r=statement
{ $value['fields'].append($r.value) }
)*
'}'
;
declaration returns [value]
: 'enum' ID
{ $value = {'id': $ID.text,
'fields': []}
}
{ list = $value['fields']
}
'{' statement[list]* '}'
;
statement[list]
: ID ':' INT ';' { $list.append({'id': $ID.text, 'value': int($INT.text)}) }
;
这取决于你想要什么,但第一个选择可能更好一些
在这里,您可以找到更多关于将值从一个规则返回到另一个规则的示例:
谢谢。我最终使用了你提到的第一个构造。还有,+=运算符的用法是什么?你是指usng+=
而不是append
(例如$value['fields']+=$r.value
与$value['fields']相比。append($r.value)
)?这有点不同,看看啊,不,我是说antlr3+=操作符。我看到了它的一些用法:c=ID('.'c+=ID)+
Ahha<代码>+=
对于拥有匹配令牌列表或收集AST非常有用,但我认为您不能简单地将其与语法规则结合使用。所以你不能只说l+=statement
(这里可能需要)。也许,您可以在声明中说(ids+=ID':'ints+=INT)*
,而不是语句*
,并处理ids
和ints
列表。但这不是一个好的解决方案;)查看权威ANTLR参考的第4.3节,或者尝试用ids+=ID
替换statement
中的ID
,然后查看生成的Python代码。