2017-08-28 56 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;