2017-08-28 57 views
0

我使用Ragel和C++作为主机来解析一些命令。这些命令从文件中读取,然后使用以下语法进行分析。Ragel中解析'换行符'的问题

该命令的语法如下::后或信号名后加逗号,

example: 

#1 Signal_representation{ 
#2  Activity: 
#3  Button_Active, 
#4  Buttons_Inactive; 
#5  Switch: 
#6  Horn, 
#7  Up_Arrow, 
#8  Right_Arrow, 
#9  Down_Arrow, 
#10  Audio,    
#11  Day_Night, Sleep, SWM_Off; 
#12 } 

这里后

Signal_representation { 
[<signal_encoding_type_name>: <signal_name> ([, <signal_name>]) ;] 
} 

现在,在上述语法这里可以有一个新行是我遵循的用于解析上述命令的Ragel语法。

action string_error { 
    cout << " ERROR::Expected string characters at line = "<< g_ReadLineNbr << endl; 
} 

action incr_Count { 
    //increment count to trace back and retrieve the string encountered 
    iGenrlCount++; 
} 

action getString { 
    std::stringstream str; 
    while(iGenrlCount > 0) 
    { 
    str << *(p - iGenrlCount); 
    iGenrlCount--; 
    } 
    str >> GeneralStr; //push the values 
} 

action getSglEncTyp { 
    cout << "Enc type = " << GeneralStr<< endl; 
    GeneralStr.clear(); 
} 

action getSgnlName { 
    cout << "Signal name = " << GeneralStr<< endl; 
    GeneralStr.clear(); 
} 

action getSgnlRepr { 
    cout << "parse ok" << endl; 
} 

action parse_error { 
    cout << "parse failed" << endl; 
} 

// my definition of Ragel grammar 

OPEN_BRACES = '{'; 
BARE_STRING = ([a-zA-Z0-9_\.\-]+) $incr_Count %getString >!(string_error); 
CLOSE_BRACES = '}'; 

//parsing starts from the parameter <signal_encoding_type_name> 

signal_repr = (space* BARE_STRING%getSglEncTyp space* ':' space* BARE_STRING%getSgnlName (space* ',' space* BARE_STRING%getSgnlName)* space* ';' space*)%/getSgnlRepr $!parse_error; 

main := signal_repr | space* ; 



//global variables in C++ prgram visible across all actions 
string GeneralStr; 
int iGenrlCount = 0; 

我面临的问题是在文件中遇到的新行。对于上面的例子,我收到以下错误 ERROR::Expected string characters at line = 2

由于每Ragel 6.10文档FSM space必须检测以下

Whitespace. [\t\v\f\n\r ]

我也曾尝试用下面的FSM替换空间:

_CR = ('\r' | '\n' | '\r\n');

但即使是上述一个不能正常工作。

有没有人遇到类似的情况?我在Stackoverflow上看到了一些关于Ragel和newline的问题,但它似乎并没有特别解决这个问题。

回答

0

您必须将逻辑分成两部分而不是一部分。

例如。未经测试

signal_repr_single_line = (space* BARE_STRING%getSglEncTyp space* ':' space* BARE_STRING%getSgnlName (space* ',' space* BARE_STRING%getSgnlName)* space* ';' space*)%/getSgnlRepr $!parse_error; 
signal_repr_multi_line = (space* BARE_STRING%getSglEncTyp space* ':' (space* BARE_STRING%getSgnlName(space* ','{1} space*))); 

signal_repr = signal_repr_single_line | signal_repr_multi_line;