2016-10-09 7 views
0

Я работаю с ANTLR4 и в процессе написания грамматики обрабатывает одиночные и двойные кавычки. Я пытаюсь использовать режимы Lexer для охвата строк, но это не работает для меня, моя грамматика указана ниже. Правильно ли это, или как я могу правильно разобрать их как токены вместо правил парсера с контекстом. Любое понимание?Обработка области для строк с одиночной и двойной кавычками в ANTLR4

Пример:

'single quote that contain "a double quote 'that has another single quote'"' 

Лексер Грамматика

lexer grammar StringLexer; 

fragment SQUOTE: '\''; 

fragment QUOTE: '"'; 

SQSTR_START: SQUOTE  -> pushMode(SQSTR_MODE); 

DQSTR_START: QUOTE  -> pushMode(DQSTR_MODE); 

CONTENTS: ~["\']+; 

mode SQSTR_MODE; 

SQSTR_END: (CONTENTS | DQSTR_START)+ SQUOTE -> popMode; 

mode DQSTR_MODE; 

DQSTR_END:(CONTENTS | SQSTR_START)+ QUOTE -> popMode; 

Parser

parser grammar StringParser; 
options { tokenVocab=StringLexer; } 

start: 
    dqstr | sqstr 
; 

dqstr: 
DQSTR_START DQSTR_END 
; 

sqstr: 
SQSTR_START SQSTR_END 
; 

ADDENDUM Благодаря @Lucas Trzesniewski для ответа.

Это часть грамматики, которую я пишу для разбора shell-подобного языка, я мог бы иметь несколько строк сценария, где они имели бы SQSTR и DQSTR. С помощью правил lexer, предоставленных в ответе, он объединяет несколько строк сценария.

Счастливый пример случай (что получить корректно распознаны с помощью ответа):

cmd 'single quote string' 
cmd2 "double quote" 
cmd3 'another single quote' 

Это получить признание в виде трех команд и трех строк (одиночных и двойных)

Неанализируемые например: С другой стороны - обратите внимание, цитата в одинарной кавычки строк:

cmd 'single "quote string' 
cmd2 "double quote" 
cmd3 'another "single quote' 

в этом случае было бы неправильно обнаружить все из них в качестве одной строки знак типа SQSTR.

Любые идеи, как решить эту проблему?

+0

Мой ответ по-прежнему действителен, даже после вашего редактирования. Попробуйте. Вложенные двойные кавычки в строке с одной кавычкой и одиночная кавычка в строке с двойными кавычками совпадают, как и любой другой символ в этой строке. Здесь ничего особенного. –

+0

@MikeLischke Привет, Майк, да, он будет обрабатывать этот случай, но есть и другие сценарии для сдерживания '' double, содержащие «single contains» double, который содержит «single», «», который потерпел бы неудачу с этой грамматикой. –

ответ

0

Путь слишком сложный, что вы имеете в виду. Где вы видели такое решение раньше? (Почти) все грамматики в хранилище грамматики на GitHub, которые имеют такие правила используют простой и хорошо работающий подход, при котором вы имеете в проводниковую, содержание и терминатор, все в одном правиле, например:

SQSTRING: '\'' .*? '\''; 
DQSTRING: '"' .*? '"'; 

Аналогично для всех другие элементы с такой структурой (одинарная кавычка, обратная тиковая цитата, многострочный комментарий и т. д.).

1

Если вы хотите, чтобы разобрать ваш пример строки в качестве одного маркеров, вы не обязательно должны использовать режимы LeXeR, вы можете использовать взаимно рекурсивные лексера правил вместо:

SQSTR : '\'' (~['"] | DQSTR)* '\''; 
DQSTR : '"' (~['"] | SQSTR)* '"'; 

Затем в парсере используйте что-то вроде:

str : SQSTR | DQSTR; 
+0

Это будет обрабатывать отдельные экземпляры строк правильно, но если у меня есть несколько экземпляров в том же фрагменте, который я пытаюсь проанализировать, он будет включать все строки в один токен. Если я добавлю «*?» чтобы он стал не жадным, он не будет обрабатывать случаи, когда строки содержат другие строки правильно. Есть идеи? –

+0

@JafarKofahi Я не понимаю, о чем вы говорите, вы можете задать новый вопрос вместе с примером. –

+0

@ Lucas Trzesniewski Я обновил свой вопрос, чтобы объяснить вопрос, который имеет эта грамматика. Я попытался обратиться к нему в различных формах, но не мог, никаких идей? –

 Смежные вопросы

  • Нет связанных вопросов^_^