2014-10-27 3 views
1

Я пытаюсь написать парсер для типа файла, который использует пары ключевых слов (разделенные пробелом), и я изо всех сил пытаюсь это сделать. Некоторые примеры лексем могут быть:Идентификация пар ключевых слов в lex

angle spring 
angle dampen 
angle collision 

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

dynamics 
    angle spring 1.0 
    angle dampen 0.0 
    angle collision 0.0 
    some 1 2 3 
    more ['stuff' 'here'] 
    tokens "values can be strings, paths, etc" 
end dynamics 

Newlines кажется значительным, я использую, что для определения если я ищу ключевое слово или просто обычную старую строку (ключевые слова должны быть первым токеном в каждой строке). Правильно ли я подхожу к этому? Должен ли я вместо этого просто различать все и более четко определять пары на этапе yacc?

Спасибо за ваше время!

+0

Я не понимаю, где проблема. Просто используйте regex 'angle \ spring', когда токенизация и синтаксический анализатор никогда не должны знать, что на самом деле он использовал пробел. Если интервал может быть произвольным, вы можете использовать регулярное выражение, например 'angle \ s + spring', чтобы определить токен ключевого слова. Если это не то, что вы хотите, вы должны уточнить, что вы имеете в виду с примером. – Bakuriu

+1

Я следую за примером зарезервированного ключевого слова, как описано в документах ply (http://www.dabeaz.com/ply/ply.html, в разделе 4.3 Спецификация токенов), который пытается сначала сопоставить ключевое слово, прежде чем решить, что это просто строка. Я могу создать специальные правила для всех токенов, которые используют пробелы, я полагаю? – spencewah

ответ

3

Проблема в том, что вы пытаетесь рассматривать логически один токен как несколько токенов. Если ключевое слово содержит пробелы, это означает, что пробелы являются частью ключевого слова token.

Если вы определяете свои ключевые слова, включая пробелы, которые вам когда-либо понадобится для обработки в парсере. Это означает, что вы должны разделить соответствие ключевых слов от соответствия нормального идентификатора.

Например:

from ply.lex import TOKEN 

KEYWORDS = [ 
    r'some', r'keyword', 
    r'keyword with token', 
    r'other keyword', 
] 

keyword = '|'.join(keyword.replace(' ', '\s+') for keyword in KEYWORDS) 

@TOKEN(keyword) 
def t_KEYWORD(t): 
    # remove spaces 
    value = ''.join(x for x in t.value if not x.isspace()) 
    return value.upper() 

Обратите внимание на @TOKEN(keyword) линии: вы можете установить строку документации о функции динамически с помощью TOKEN декоратора. Это позволяет использовать сложные выражения для определения токенов, даже если их определение «требует» с использованием выражения, а не простых строковых литералов.


Альтернатива заключается в том, чтобы рассматривать ключевые слова, разделенные пробелами, как несколько ключевых слов. Таким образом, вы сохраняете обычное определение идентификаторов и ключевых слов и изменяете свою грамматику, чтобы использовать несколько ключевых слов вместо одного.

Например, вы бы правила грамматики, как:

def p_dynamics(p): 
    'DYNAMICS BLOCK END DYNAMICS' 

вместо:

def p_dynamics(p): 
    'DYNAMICS BLOCK END_DYNAMICS' 

В зависимости от контрсилами у вас есть одно решение может быть проще реализовать.