【记录】使用Eclipse开发Antlr:创建antlr项目并编译

【背景】

之前花了很多精力,终于下载到Antlr的Eclipse插件并安装成功:

【记录】折腾Antlr的Eclipse插件

并且配置好antlr:

【记录】配置Eclipse中的antlr

现在就可以用Eclipse去折腾Antlr的开发了。


1.参考:

Antlr+Eclipse开发环境的搭建

去新建一个java项目:

new a java project

hart eddl antlr project

finish for antlr project

就可以新建好此java的项目了:

newly created java project for antlr

2.选中该java项目后,

再去新建项目:

harteddl new other

choose antlr combined grammar

create a new combined grammar using antlr

3.然后就可以新建出对应的antlr的语法文件了:

antlr g file created in eclipse

然后写入新的内容:

grammar HartEddl;

/*
Notes:
1. HART EDDL Spec
can find from
hart 7.3 -> SPEC500.pdf, that is Device Description Language Specification
*/
options {
	output = AST;
	ASTLabelType = CommonTree; // type of $stat.tree ref etc...
}

COMMENT
    :   '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;

WS  :   ( ' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};

//fragment
ID  :	('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;

fragment
DIGIT
	:	'0'..'9';

fragment
OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

//fragment
STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;


fragment
IMPORTED_VALUE	:	'[' ID ']'; /* normal ID with [] */

//fragment
DEFINE_IMPORTED_VALUE
		:	ID | IMPORTED_VALUE;

fragment
HEX_DIGIT 	: ('a'..'f'|'A'..'F' | DIGIT) ;
//fragment
HEX_VALUE	:	'0x' HEX_DIGIT+;

//fragment
DECIMAL_VALUE	: 	DIGIT+;

//fragment
direct_value 	:	(DECIMAL_VALUE | HEX_VALUE);

string_value	:	(DEFINE_IMPORTED_VALUE | STRING);

expression_or_direct_value
		:	direct_value; //todo: add expression support
expression_or_string
		:	STRING;//todo:add string expression support


/*******************************************************************************
Main Entry Rule
*******************************************************************************/
startParse	:	(singleInclude | idInfos | variable | command | collection | menu)+;

/*******************************************************************************
include
*******************************************************************************/
singleInclude	:	'#include' STRING;

/*******************************************************************************
EDDL Identification Info
*******************************************************************************/
idInfos		:	idinfo (',' idinfo)+;
idinfo		:	idInfoKey idInfoValue;
idInfoKey	:	'MANUFACTURER' | 'DEVICE_TYPE' | 'DEVICE_REVISION' | 'DD_REVISION';
idInfoValue	:	direct_value | DEFINE_IMPORTED_VALUE;


/*******************************************************************************
Common definitions
*******************************************************************************/
common_label	:	'LABEL' string_value+ ';';
common_help	:	'HELP' help_value ';';



/*******************************************************************************
7.27 VARIABLE
Table 138 – VARIABLE attributes
*******************************************************************************/
variable	:	'VARIABLE' variable_identifier '{' variable_body '}';
variable_identifier
		:	ID;
variable_body	:	variable_field+;
variable_field	:	variable_class | variable_label | variable_type | variable_help | constant_unit | variable_handling;
variable_class	:	'CLASS' class_value ';' ;
class_value	:	single_class_value ('&' single_class_value)*;
single_class_value
		: 	('ALARM'| 'ANALOG_INPUT'| 'ANALOG_OUTPUT'| 'COMPUTATION'| 'CONTAINED'| 'CORRECTION'| 'DEVICE'| 'DIAGNOSTIC'| 'DIGITAL_INPUT'| 'DIGITAL_OUTPUT'| 'DISCRETE_INPUT'| 'DISCRETE_OUTPUT'| 'DYNAMIC'| 'FREQUENCY_INPUT'| 'FREQUENCY_OUTPUT'| 'HART'| 'INPUT'| 'LOCAL'| 'LOCAL_DISPLAY'| 'OPERATE'| 'OUTPUT'| 'SERVICE'| 'TUNE');
variable_label	:	common_label;
variable_type	:	integer_type_value | float_type_value | enumarated_type_value | bitEmurated_type_value; //todo: add more

values_display_format
		:	'DISPLAY_FORMAT' expression_or_string ';';
values_default_value
		:	'DEFAULT_VALUE' expression_or_direct_value ';';
enumarated_value:	direct_value;
enumarated_desc	:	string_value;
enumarated_help	:	string_value;
enumarated_desc_help
	:	enumarated_desc_help_call | enumarated_desc_help_direct;
enumarated_desc_help_direct
	:	enumarated_desc (',' enumarated_help)?;
enumarated_desc_help_call
	:	ID '(' direct_value ')'; // call some variable
//	:	variable_identifier '(' direct_value ')'; // call some variable
//	:	'units_code(57)'; // call some variable
	
//Note:
//7.27.2.2.3.2 ENUMERATED
//[(description, value, help)<exp>]+,
//should be
//[(value, description, help)<exp>]+,
values_enumarated
		:	'{' enumarated_value ',' enumarated_desc_help '}' ','?; //TODO: add DEFAULT_VALUE,help,INITIAL_VALUE,size
//7.27.2.2.3.2 ENUMERATED
enumarated_type_value
		:	'TYPE' 'ENUMERATED' '{' values_enumarated+ '}';

values_attribute
		:	values_default_value | values_display_format;//todo: add more EDIT_FORMAT, ...
float_type_value
		:	'TYPE' 'FLOAT' '{' values_attribute+ '}';
integer_type_value
		:	'TYPE' 'INTEGER' '{' values_attribute+ '}';

bitEnumarated_action	:	ID ('&' ID)* ('(' ID '&' ID ')')?;
bitEnumarated_value	:	direct_value;
bitEnumarated_desc	:	string_value;
values_bitEnumarated
		:	'{' bitEnumarated_value ',' bitEnumarated_desc (',' bitEnumarated_action)?'}' ','?;
bitEmurated_type_value
		:	'TYPE' 'BIT_ENUMERATED' '{' values_bitEnumarated+ '}';

constant_unit	:	'CONSTANT_UNIT' string_value ';' ;

variable_help	:	common_help;
help_value	:	string_value;

/*
7.27.2.5 HANDLING
*/
single_handling_value
		:	('READ' | 'READ_WRITE' | 'WRITE');
handling_value	:	single_handling_value ('&' single_handling_value)*;
variable_handling
		:	'HANDLING' handling_value ';' ;


/*******************************************************************************
7.7 COMMAND
*******************************************************************************/
command		:	'COMMAND' command_identifier '{' command_body '}';
command_body	:	command_field+;//command_number command_operation command_transaction+ command_responseCode*;
command_field	:	command_number | command_operation | command_transaction | command_responseCode;
command_identifier
		:	ID;
command_number	:	'NUMBER' direct_value ';';	

command_operation
		:	'OPERATION' command_operation_attr  ';';	
command_operation_attr
		:	'READ'|'WRITE'|'COMMAND'|'DATA_EXCHANGE'|string_value;
	
command_transaction
		:'TRANSACTION' command_transaction_number? '{' command_transaction_body '}';
command_transaction_number
		:	direct_value;
command_transaction_body
		:	command_transaction_request command_transaction_reply command_transaction_responseCode*;
//for HART EDDL
//9.1 Transactions
command_transaction_request
		:	'REQUEST' '{' request_reply_dataItem? (',' request_reply_dataItem)* '}'; //TODO: add more for: Table 46 – REPLY and REQUEST attributes
command_transaction_reply
		:	'REPLY' '{' request_reply_dataItem (',' request_reply_dataItem)* '}';
request_reply_dataItem
		:	direct_value | request_reply_dataItem_reference;
request_reply_dataItem_reference
		:	ID; //TODO: add "9.1.1 Data Item Masks", "9.1.2 Data Item Qualifiers", ""

/*
//for Profibus EDDL
command_transaction_request
		:	'REQUEST' '{' request_reply_attibutes '}'; //TODO: add more for: Table 46 – REPLY and REQUEST attributes
command_transaction_reply
		:	'REPLY' '{' request_reply_attibutes '}';
request_reply_attibutes
		:	(requestReply_attibute_reference (',' requestReply_attibute_itemMask (',' requestReply_attibute_info (',' requestReply_attibute_index)?)?)?)?;
	//here set to optional, which is not confrom to :
	//Table 46 – REPLY and REQUEST attributes
	//but can match our demo file, which REQUEST is empty
requestReply_attibute_reference
		:	ID;
requestReply_attibute_itemMask
		:	ID;
requestReply_attibute_info
		:	ID;
requestReply_attibute_index
		:	ID;
*/
command_transaction_responseCode
		:	command_responseCode;

command_responseCode
		:	'RESPONSE_CODES' '{' responseCode_body '}';
responseCode_body
		:	responseCode_exp+;
responseCode_exp: 	responseCode_exp_value ',' responseCode_exp_type ',' responseCode_exp_description (','? responseCode_exp_help)? ';';
responseCode_exp_value
		:	direct_value;
responseCode_exp_type
		:	'DATA_ENTRY_ERROR'|'DATA_ENTRY_WARNING'|'MISC_ERROR'|'MISC_WARNING'|'MODE_ERROR'|'PROCESS_ERROR'|'SUCCESS';
responseCode_exp_description
		:	string_value;
responseCode_exp_help
		:	string_value;


/*******************************************************************************
7.6 COLLECTION in Profibus EDDL
8.4 Collections in HART EDDL
*******************************************************************************/
collection	:	'COLLECTION' collection_name '{' collection_body '}';
collection_name	:	collection_of | ID;
collection_of	:	'OF' collection_attr_itemType ID;
collection_body
		:	collection_attribute+;
collection_attribute
		:	collection_attr_lable | collection_attr_help | collection_attr_members; //collection_attr_validity
collection_attr_lable
		:	common_label;
collection_attr_help
		:	common_help;
collection_attr_itemType
		:	'AXIS' | 'BLOCK_A' | 'BLOCK_B' | 'CHART' | 'COLLECTION' | 'COMMAND' | 'CONNECTION' | 'DOMAIN' | 'EDIT_DISPLAY' | 'FILE' | 'GRAPH' | 'LIST' | 'MENU' | 'METHOD' | 'PROGRAM' | 'RECORD' | 'REFERENCE_ARRAY' | 'REFRESH' | 'RESPONSE_CODES' | 'SOURCE' | 'UNIT' | 'VALUE_ARRAY' | 'VARIABLE' | 'VARIABLE_LIST' | 'WAVEFORM' | 'WRITE_AS_ONE';
collection_attr_members
		:	'MEMBERS' '{' collection_attr_members_body '}';
collection_attr_members_body
		:	collection_attr_members_item+;
collection_attr_members_item
		:	collection_attr_members_item_name ',' collection_attr_members_item_ref (',' collection_attr_members_item_desc ',' collection_attr_members_item_help)? ';';
collection_attr_members_item_name
		:	ID;
collection_attr_members_item_ref
		:	ID;
collection_attr_members_item_desc
		:	DEFINE_IMPORTED_VALUE;
collection_attr_members_item_help
		:	DEFINE_IMPORTED_VALUE;


/*******************************************************************************
7.18 MENU
10.1 Menus
*******************************************************************************/
menu	:	'MENU' menu_identifier '{' menu_body '}' ;
menu_identifier
	:	ID;
menu_body
	:	menu_attribute+;
menu_attribute
	:	menu_label | menu_items; //TODO: add help,...
menu_label
	:	common_label;
menu_items
	:	'ITEMS' '{' menu_items_body '}';
menu_items_body
	:	menu_item (',' menu_item)*;
menu_item
	:	ID menu_item_attributes?;
menu_item_attributes
	:	'(' menu_item_attribute (',' menu_item_attribute)* ')';
menu_item_attribute
	:	'DISPLAY_VALUE' | 'HIDDEN' | 'READ_ONLY' | 'NO_LABEL' | 'NO_UNIT' | 'REVIEW';

变成:

copy into the antlr grammar code

注意到,其.g的语法文件下面,除了Grammar,还有对应的Interpreter和Railroad View。

4.然后再去转换为Antlr项目:

configure Convert to ANTLR project

然后什么变化好像都没有。

不过再去查看选项时,就没了Configure项了:

no configure option anymore

5.然后就可以去编译项目了:

antlr project then build project

对应的,编译成功后:

can found generated lexer and parser java and token file and console output

console中有对应的log输出:

ANTLR Parser Generator  Version 3.5.

Using project classpath: No.

Grammar: D:\DevRoot\android\android_root\HartEddl\HartEddl.g

BUILD SUCCESSFUL

Total time: 1 second

然后也生成了对应的输出文件夹output和对应的lexer和parser的java文件,以及token文件。

至此,编译.g文件,算是OK了。

6.不过,此时注意到,当前环境下,还是无法识别antlr的库的:

can not recognize antlr lib

鼠标移动上去,出现提示:

fix project setup for antlr lib

但是却看到检测出来的antlr的jar是3.4的:

projects setup fixes but is antlr 3.4 complete jar not 3.5 jar

不是我们之前配置antlr时所添加的3.5的。

7.所以,此处不用此办法。

而是自己去添加正确的路径去:

右击antlr项目->Properties->Java Build Path -> Libraries -> Add External JARs

right antlr project choose properties

java build path libraries add external jars

添加对应的antlr的complete的jar包,此处为antlr-3.5-complete.jar,即可:

added external antlr complete 3.5 jar lib

然后项目中的代码,就可以找到antlr的库,就可以消除错误了:

then can see referenced lib and code is ok

 

【总结】

至此,创建并编译antlr的项目,就完成了。


接着,就是去折腾如何调试antlr代码:

【记录】使用Eclipse开发Antlr:如何调试antlr项目



发表评论

电子邮件地址不会被公开。 必填项已用*标注

无觅相关文章插件,快速提升流量