Lexer - How to handle conflicts? (Menhir)

Hey! I am setting up a tiny DSL, with the structure:

user: id uuidv4, name name

The idea is to generate CSV files based on this, and I am trying to figure out how to handle conflicting lexer rules. I have the following:

let white = [' ' '\t']+
let newline = '\r' | '\n' | "\r\n"
let id = ['a'-'z' 'A'-'Z' '_' '-']*
rule read = 
  parse 
  | id { IDENTIFIER (Lexing.lexeme lexbuf) }
  | "uuidv4" { UUIDV4 }
  | "name" { NAME }

And then

expr:
  | tbl = IDENTIFIER; COLON; r = row; NEWLINE; e = expr { Table (tbl,r, e) }
  | tbl = IDENTIFIER; COLON; r = row; SEMICOLON; e = expr { Table (tbl,r, e) }
  | tbl = IDENTIFIER; COLON; r = row { Table (tbl,r, End) }
  ;

row: 
  | row_title = IDENTIFIER; NAME; COMMA; r = row { Name (row_title, r) }
  | row_title = IDENTIFIER; NAME { Name (row_title, End) }
  ;

And the challenge is that the lexer never identifier name because it has a conflict with id, is there any way to make it use a different lexer depending on the situation? Or how do I best resolve this?

In the parser, you can define a production that recognizes both an identifier and name, and then you can use it in the other productions:

id_or_name:
  | IDENTIFIER { $1 }
  | NAME { "name" }

expr:
  | tbl = id_or_name; ...
1 Like

Thanks! This solved the issue.