Как захватить строку без кавычек - PullRequest
4 голосов
/ 21 ноября 2011

Я пытаюсь захватить строки в кавычках без кавычек. У меня есть этот терминал

%token <string> STRING

и это производство

constant:
    | QUOTE STRING QUOTE { String($2) }

вместе с этими правилами лексера

| '\''       { QUOTE }
| [^ '\'']*  { STRING (lexeme lexbuf) } //final regex before eof

Кажется, что все, что приводит к QUOTE, интерпретируется как одна лексема, которая не разбирается. Так что, возможно, моя проблема в другом месте грамматики - не уверен. Я иду об этом правильным путем? Это было хорошо, когда я пытался исключить кавычки из строк.

Обновление

Я думаю, что может быть некоторая двусмысленность со следующими правилами лексера

let name = alpha (alpha | digit | '_')*
let identifier = name ('.' name)*

Следующее правило предшествует STRING

| identifier    { ID (lexeme lexbuf) }

Есть ли способ устранить их неоднозначность без включения кавычек в регулярное выражение STRING?

Ответы [ 3 ]

5 голосов
/ 22 ноября 2011

Вполне нормально выполнять семантический анализ в лексере для констант, таких как строки и числовые литералы, поэтому вы можете рассмотреть правило lex для ваших строковых констант, таких как

| '\'' [^ '\'']* '\'' 
    { STRING (let s = lexeme lexbuf in s.Substring(1, s.Length - 2)) }
1 голос
/ 21 ноября 2011

Вы можете использовать лексему с кавычками, но обрезать кавычки в парсере

Lexer:

let constant       = ("'" ([^ '\''])* "'")
...
| constant         { STRING(lexeme lexbuf) } 

Parser:

%token <string> STRING

...
constant:
    | STRING { ($1).Trim([|'''|]) }

Или , если вы хотите извлечь цитаты из строки:

Лексер:

let name = alpha (alpha | digit | '_')*
let identifier = name ('.' name)*
...

| '\''       { QUOTE }
| identifier { ID (lexeme lexbuf) }
| _          { STRING (lexeme lexbuf) } 

идентификатор будет убирать символы из STRING, поэтому Ваш лексемный поток может быть таким: QUOTE ID STRING ID .. QUOTE , и вы должны обработать это в парсере:

Parser:

constant:
     | QUOTE content QUOTE     { String($2) }

content:
     | ID content      { $1+$2 }
     | STRING content  { $1+$2 }
     | ID              { $1 }
     | STRING          { $1 }
0 голосов
/ 10 января 2014

У меня была похожая проблема. Я фиксирую их в файле "lexic.l", используя состояния. Вот мой автоответ

...