2012-08-04 37 views
0

在我lexer.mll我宣布EOS如下:的空间让line_terminator识别

let line_feed = '\n' (* %x200A *) 
let carriage_return = '\r' (* %x200D *) 
let line_terminator = line_feed | carriage_return | carriage_return line_feed 
(* KO: %x2028 | %x2029 *) 
let LINE_END = line_terminator 

let tab_character = '\x09' (* CHARACTER TABULATION *) 
let eom_character = '\x19' (* END OF MEDIUM *) 
let space_character = '\x20' (* SPACE *) 
let underscore = '\x5F' (* LOW LINE or SPACING UNDERSCORE *) 

let WSC = tab_character | eom_character | space_character 
let line_continuation = WSC* underscore WSC* line_terminator 
let WS = (WSC | line_continuation)+ 
let EOL = WS? LINE_END 
let EOS = EOL* 

rule token = parse 
    | WS  { token lexbuf } 
    | LINE_END { newline lexbuf; token lexbuf } 
    | EOS  { EOS } 

在我parser.mly,我有这样的事情:

%token EOS 
... 
%% 
nonterminal : 
    statement EOS 
    statement { semantic-action } 

编辑我test_KO.txt如下Emacs,它在解析时产生错误:

a_statement 
b_statement 

不过,如果我a_statement如下之后添加一个space,它通过解析:

a_statement(space) 
b_statement 

我想原因是line_terminator不能test_KO.txt承认,虽然a_statemntb_statement不在同一直线上;如果它们之间有一个space,则可以识别出line_terminator

您是否认为将x2028x2029添加到line_terminator会解决问题?由于ocamllex可能不支持unicode,所以测试它会很复杂......

否则,有没有其他解决方案的问题?

+0

您是否解决了问题?什么是a_statement和b_statement的解析规则?有很多可能性。 – didierc 2012-10-26 15:02:07

回答

2

问题是,您的WS,LINE_END和EOS规则都可以尝试匹配相同的字符串,请参阅the OCamllex manual中用于选择哪个正则表达式实际匹配的“最长匹配”规则。

当您在语句之间只有一行代码行时,'LINE_END'和'EOS'规则仅匹配1个字符,但'LINE_END'规则会更早出现,因此会被选中。没有EOS令牌被发射,并且您从语法中得到一个错误。

当你有两个空格和行结束了“WS”将匹配1个字符, 和规则EOS将匹配两个(包括空格和换行)的规则,因此对于EOS规则被选中。 EOS令牌现在发出,您的语法按预期工作。

最容易的可能是从您的词法分析器和语法中删除EOS令牌。