2015-03-12 3 views
1

Я пишу программу, которая позволяет команду (в основном строку до новой строки), содержащую несколько параметров, разделенных пробелами.Flex/Bison: общий способ tokenize ключевых слов, разделенных пробелами/вкладками

Like: arg1 arg2 arg3 arg4 (\n) 

я могу использовать сам регулярное выражение для достижения этой цели, как показано ниже:

arg1[ \t]+ {return T_ARG1;} 
arg2[ \t]+ {return T_ARG2;} 
arg3[ \t]+ {return T_ARG3;} 
arg4[ \t]+ {return T_ARG4;} 

Но я не уверен, что это лучший способ сделать это, как это? Можете ли вы предложить общий способ использования Flex?

Примечание: Я также разрешаю команду, введенную через несколько строк, игнорируя шаблон [\\ n].

+2

Являются ли аргументы действительно ключевыми словами? Или это произвольные пробельные разделенные слова? Другими словами, пытаетесь ли вы распознать набор фиксированных слов в любом порядке или создать вектор аргументов в том порядке, в котором они были введены? – rici

+0

Да, я пытаюсь распознать набор фиксированных слов в некотором порядке. –

+0

Я пытаюсь создать команду (например, команду linux), используя flex и bison. Заказ: arg1 arg2 arg3 arg4 Примечание: означает минимальное пространство. –

ответ

0

Важно ли, чтобы разделители были включены в лексему? Обычно это не так, и мы можем просто отказаться от какой-либо из сепараторов, оставляя маркеры для самих аргументов:

[ \t\n\r]+  ; /* Skip */ 
arg1  return T_ARG1; 
arg2  return T_ARG2; 
arg3  return T_ARG3; 
arg4  return T_ARG4; 
+0

Например, ip addradd (in inux дает мне ошибку) Объект «addradd» неизвестен, попробуйте «ip help». Потому что между addr и add должно быть пространство. –

+1

Я тоже пробовал свой код. Но он принимает arg1arg2arg3arg4, которого я не хочу. Я хочу, по крайней мере, один пробел между двумя словами. –

1

с использованием arg1[ \t]+ не является хорошей идеей, потому что вы возвращаете «грязный» token- нужного маркера с лишними пробелами, и вы можете захотеть удалить их позже (это означает больше разбора).

Помните, что прогибается жаден:

If it finds more than one match, it takes the one matching the most text (for trailing context rules, this includes the length of the trailing part, even though it will then be returned to the input). If it finds two or more matches of the same length, the rule listed first in the flex input file is chosen.

поэтому он будет пытаться соответствовать большой текст, и он будет рассматривать порядок шаблон только в случае длины равенства. Так что вам нужно расставить приоритеты арга, затем положить шаблон, который будет соответствовать остальным словам:

WHITESPACE [\t\n\r ] 
DIGIT   [0-9] 
LETTER  [a-zA-Z] 
%% 
arg1     return T_ARG1; 
arg2     return T_ARG2; 
arg3     return T_ARG3; 
arg4     return T_ARG4; 
(LETTER|DIGIT|[_])+ printf("error! unknown command\n"); 
WHITESPACE   ; 
%% 

Вы можете использовать [:digit:] или просто [0-9] вместо DIGIT я определена, см here для более стандартных выражений.

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