我试图将带括号的输入标记化,以便我可以创建一棵树。这是我到目前为止所写的:
void parse(){
int ch, i = 0;
char temp[10*MAX] = {0};
while ((ch = getchar()) != EOF){
if(isspace(ch)){
continue;
}else if(ch == ')'){
/* go one level up in the tree*/
}else if(ch != '(' && ch != ']'){
temp[i++] = ch;
}
else{
/*add child or sibling*/
printf("%s\n", temp);
parse();
}
}
}
这是上面代码的结果
////////INPUT/////////////////////
BIKE(2*WHEEL(RIM[60.0 ],
2*AXLE, ------------>PROBLEMATIC
SPOKE[120.],
HUB(2*GEAR[25.],AXLE(5*BOLT[0.1], 7 * NUT[.15]))),
FRAME(REARFRAME [175.00],
1*FRONTFRAME (FORK[22.5] ,AXLE, 2 *HANDLE[10.])))-------->PROBLEMATIC
//////////////OUTPUT/////////////
BIKE
2*WHEEL
RIM[60.0
,2*AXLE,SPOKE[120.--->PROBLEMATIC
,HUB
2*GEAR[25.
,AXLE
5*BOLT[0.1
,7*NUT[.15
,FRAME
REARFRAME[175.00
,1*FRONTFRAME
FORK[22.5
,AXLE,2*HANDLE[10.--->PROBLEMATIC
零指数的逗号对我来说很重要。它在此之前签署当前令牌是否是孩子或令牌的兄弟,所以我需要它。但是由于输入不完全严格,因此存在一个小问题。我标记了I / O中麻烦的线条。
我应该为一个令牌获取一个名称。在输出中,有两行具有两个名称,因为输入中没有括号。为了解决这个问题,我想我可以编写一个函数来检查temp
是否有两个逗号,然后再解析另一个函数。但是,当然,更好的方法是parse()
功能。是否可以为这些目的修改代码?
输入的BNF表示法如下。
<part> ::= <composite part> | <basic part>
<composite part> ::= <name> | <name> ( <list of items> )
<basic part> ::= <name> | <name> [ <price> ]
<item> ::= <part> | <quantity> * <part>
<list of items> ::= <item> | <item>, <list of items>
<name> ::= <uppercase letter sequence of maximal length 20>
<quantity> ::= <positive integer>
<price> ::= <floating point>
此外,在提供BNF表示法时,是否有任何系统的步骤?我总是想提出最通用的解决方案,但是经常遇到这些问题。