在我的lexer.mll中,我按如下方式声明了EOS:
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 }我在Emacs下编辑我的test_KO.txt,如下所示,它在解析时引发错误:
a_statement
b_statement但是,如果我在a_statement后面添加一个space,如下所示,它会通过解析:
a_statement(space)
b_statement我猜是因为test_KO.txt不能识别line_terminator,尽管a_statemnt和b_statement不在同一行;如果它们之间有一个space,就可以识别line_terminator。
你认为在line_terminator中添加x2028和x2029会解决这个问题吗?由于ocamllex可能不支持unicode,所以测试它会很复杂……
否则,有没有其他的解决方案呢?
发布于 2013-04-21 20:31:17
问题是您的WS、LINE_END和EOS规则都可以尝试匹配相同的字符串,有关用于选择哪个正则表达式实际匹配的“最长匹配”规则,请参阅the OCamllex manual。
当语句之间只有一个行终止符时,'LINE_END‘和'EOS’规则都只匹配1个字符,但'LINE_END‘规则出现得更早,因此它被选中。不会发出EOS令牌,并且您的语法会出现错误。
如果同时具有空格和行终止符,则“WS”的规则将匹配1个字符,而EOS的规则将匹配两个字符(空格和换行符),因此选择了EOS的规则。现在发出了一个EOS令牌,您的语法按预期工作。
最简单的方法可能是从词法分析器和语法中删除EOS标记。
https://stackoverflow.com/questions/11806323
复制相似问题