乐者为王

Do one thing, and do it well.

使用ANTLR构建PowerScript语法分析器(4)

到目前为止,PowerScript的词法分析已经完成的差不多了,接下来就要开始实现它的语法规则。我们准备先从表达式(expression)开始下手,因为它是语法规则中最核心的部分。

简单的来说,表达式是计算的最小单元,是可以被计算产生值的代码的任何部分。一般是由一个或多个运算元和通常是一个运算符构成,运算元本身也可以是表达式。这样层层递归嵌套,直到被称为基本表达式(primary expression)的最简单部分。

基本表达式包含有标志符、字面量(literal)、字段存取、函数调用和数组存取等,圆括号括起的表达式通常也被认为是基本表达式。以下是它们的大致表现形式:

1
2
3
4
5
6
rating
'This is a string'
x.y
f(x)
a[x]
(x)

在PowerScript中调用函数和事件的语法如下:

1
{ objectname. } { ancestorname :: } { type } { calltype } { when } name ( { argumentlist } )

其中,花括号中的项表示可以有可以无。type有两个值function和event,calltype有两个值static和dynamic,when有两个值trigger和post,并且type,calltype和when的顺序可以任意调换。如果ancestorclass是当前对象的直接父类的话,那么可以使用super关键字代替。

这里是收集的一些基本表达式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
this.ls_array[1]
this.event pfc_addrow()
this.event rowfocuschanged(ll_row)
this.event post doubleclicked(xpos, ypos, row, dwo)
this.uo_1.function hallo()
post function column_order_update_from_grid()
event ue_process()

close(parent)
parent.enabled
parent.hide()
parent.event ue_postconstructor()
parent.function static trigger wf_process( )
parent.post uf_process_item ()

super::create
super::event clicked()
super::event clicked(xpos, ypos, row, dwo)
super::of_remove_tail(anv_tailnode)
super::event trigger selectionchanging(oldindex, newindex)

iu_tab_postings.post of_enable_sort(dw_main, dw_detail, false)
lw_sheet.dynamic event pfc_close()
w_main.event doubleclicked(flags, xpos, ypos)
dw_main.event pfc_retrieve()
cb_ok.event trigger clicked()
cb_ok.triggerevent(clicked!)

有了以上的这些信息,我们就可以很容易地得到基本表达式的语法规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
expression_list
    : expression (',' expression)*
    ;

expression
    : primary_expression
    ;

primary_expression
    : '(' expression ')'
    | (object_name '.')* (ancestor_name '::')? call_specifier* IDENTIFIER identifier_suffix?
    | literal
    | '::'? object_name
    ;

object_name
    : 'this'
    | 'parent'
    | IDENTIFIER
    ;

ancestor_name
    : 'super'
    | IDENTIFIER
    ;

call_specifier
    : 'function'
    | 'event'
    | 'static'
    | 'dynamic'
    | 'trigger'
    | 'post'
    ;

identifier_suffix
    : arguments ('.' IDENTIFIER arguments)*    // cascaded calling
    | '[' expression_list? ']'
    ;

arguments
    : '(' expression_list? ')'
    ;

literal
    : STRING_LITERAL
    | INTEGER_LITERAL
    | FLOAT_LITERAL
    | BOOLEAN_LITERAL
    | LINE_COMMENT
    | BLOCK_COMMENT
    ;

不过,如果到这里就开始用ANTLR工具生成词法分析器和语法分析器的话,你会得到一堆的警告信息。要消除这些警告需要在语法文件头部添加:

1
2
3
options {
    backtrack=true;
}

它的作用是告诉ANTLR在LL(*)语法分析失败的时候要去尝试匹配其它选项。

Comments