我有以下解析代码,但是我得到了非终端表达式和function_call之间的转换/减少冲突。这是Visual Basic编程语言的一个小解析代码。 CFG会错吗?或者问题只在于那两个非终端符号。
program ::= function_declarations:functionDeclarations
| /* Vacio */
;
function_declarations ::= function_declaration:functionDeclaration function_declarations:functionDeclarations
;
function_declaration ::= structure_statement:structureStatement
|sub_statement:subStatement
|function_statement:functionStatement
;
structure_statement ::= TK_STRUCTURE TK_ID statements:stmnts TK_END TK_STRUCTURE
;
sub_statement ::= TK_SUB TK_ID TK_PARIN parameters:prmts TK_PAROUT statements:stmnts TK_END TK_SUB
;
function_statement ::= TK_FUNCTION TK_ID TK_PARIN parameters:prmts TK_PAROUT statements:stmnts TK_END TK_FUNCTION
|TK_FUNCTION TK_ID TK_PARIN parameters:prmts TK_PAROUT TK_AS data_type:type statements:stmnts TK_END TK_FUNCTION
;
parameters ::= parameter:prmt TK_COMMA parameters:prmts
|parameter:prmt
| /* Vacio */
;
parameter ::= parameter_type:prmt_type TK_ID TK_AS data_type:type
;
parameter_type ::= TK_BYVAL
| TK_BYREF
;
data_type ::= TK_INTEGER
|TK_BOOLEAN
|TK_STRING
;
statements ::= statement:stmnt statements:stmnts
| /* Vacio */
;
statement ::= if_statement:ifStatement
|while_statement:whileStatement
|for_statement:forStatement
|do_statement:doStatement
|variable_declaration:var_declare
|expression:expr
|TK_RETURN expression
|TK_EXIT
;
if_statement ::= TK_IF expression:expr TK_THEN statements:stmnts TK_END TK_IF
|TK_IF expression:expr TK_THEN statements:stmnts TK_ELSE statements:stmnts TK_END TK_IF
|TK_IF expression:expr TK_THEN statements:stmnts elseif_statements:elseifStmnts TK_END TK_IF
|TK_IF expression:expr TK_THEN statements:stmnts elseif_statements:elseifStmnts TK_ELSE statements:stmnts TK_END TK_IF
;
elseif_statements ::= elseif_statement:elseifStmnt elseif_statements:elseifStmnts
|elseif_statement:elseifStmnt
;
elseif_statement ::= TK_ELSEIF expression:expr TK_THEN
;
for_statement ::= TK_FOR variable_declaration:var_declare TK_TO expression:expr statements:stmnts TK_NEXT
|TK_FOR variable_declaration:var_declare TK_TO expression:expr TK_STEP TK_NUMBER statements:stmnts TK_NEXT
;
while_statement ::= TK_WHILE expression:expr statements:stmnts TK_END TK_WHILE
;
do_statement ::= TK_DO TK_WHILE expression:expr statements:stmnts TK_LOOP
|TK_DO statements:stmnts TK_LOOP TK_UNTIL expression:expr
;
variable_declaration ::= variable_declarator:var TK_COMMA variable_declaration:var_declare
|variable_declarator:var
;
variable_declarator ::= TK_DIM TK_ID TK_AS data_type:type TK_EQUALS expression:expr
|TK_ID TK_AS data_type:type TK_EQUALS expression:expr
|TK_DIM TK_ID TK_EQUALS expression:expr
|TK_ID TK_EQUALS expression:expr
|TK_DIM TK_ID TK_AS TK_NEW data_type:type TK_EQUALS expression:expr TK_PARIN arguments:args TK_PAROUT
|TK_ID TK_EQUALS TK_NEW data_type:type TK_PARIN arguments:args TK_PAROUT
;
expression ::= numeric_expression:num_exp
|boolean_expression:bool_exp
|logical_expression:logic_exp
|literal_expression:lit_exp
|TK_ID:id
|function_call:call
;
boolean_expression ::= expression:e1 TK_GREATERTHAN expression:e2
|expression:e1 TK_LESSTHAN expression:e2
|expression:e1 TK_GREATEREQUAL expression:e2
|expression:e1 TK_LESSEQUAL expression:e2
|expression:e1 TK_EQUALS expression:e2
;
logical_expression ::= TK_NOT expression:e1
|expression:e1 TK_OR expression:e2
|expression:e1 TK_AND expression:e2
|expression:e1 TK_XOR expression:e2
|TK_TRUE
|TK_FALSE
;
numeric_expression ::= expression:e1 TK_SUM expression:e2
|expression:e1 TK_MINUS expression:e2
|expression:e1 TK_PRODUCT expression:e2
|expression:e1 TK_DIVISION expression:e2
;
literal_expression ::= TK_NUMBER
|TK_STRINGVAL
;
function_call ::= TK_ID TK_PARIN arguments:args TK_PAROUT
|TK_ID TK_PARIN TK_PAROUT
;
arguments ::= argument TK_COMMA expression:expr
;
argument ::= expression:expr
;
什么可能给我带来麻烦?
答案 0 :(得分:0)
问题是没有任何东西将一个陈述与下一个陈述分开。 expression
是一个有效的语句,因此两个连续的表达式是有效的statements
。但是,那么,单一陈述也是如此。
现在ID
是expression
,带括号的表达式是表达式。所以first. (second)
是两个statement
s,¿或者它是函数调用?在第一种情况下,您需要将ID
缩减为expression
(然后statement
)。在第二种情况下,您只需移动(。
因此,转移减少冲突。