2012-02-26 1 views
0

Предположим, что у меня есть тип данных в Haskell, как это:Haskell типа данных по шаблону в Alex

data Token = THEN AlexPosn 
      | ELSE AlexPosn 

от Алекса, я понимаю, что:

data AlexPosn = AlexPn !Int !Int !Int 
    deriving (Eq,Show) 

Я могу сделать шаблон согласования, как это:

eat_token :: Token -> [Token] -> [Token] 
eat_token (THEN p1)((THEN p2):rest) = rest 
eat_token (ELSE p1)((ELSE p2):rest) = rest 

Но то, что я действительно хочу сделать вот это:

eat_token (_ p) tk2 = error "Syntax Error at:"++(show p) 

Однако, я получаю:

Parse error in pattern. 

Любые предложения?

+0

Написать функцию, которая извлекает поле AlexPosn из разных лексем. – Ingo

ответ

2

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

data Token = Token TokenType AlexPosn 
data TokenType = THEN | ELSE 

Затем, вы можете легко сделать матч шаблон, который вы хотели:

eat_token (Token _ p) tk2 = error $ "Syntax Error at: " ++ show p 
+1

Это идиома «все» использует с Алексом, но обычно с другой схемой именования (люди должны работать из того же оригинального примера). Перечислите все токены в одном типе данных, затем оберните перечисление в другой тип данных вместе с исходной позицией. Люди называют завернутый тип токена и исходную позицию «Lexeme». –

0
eat_token (_ p) tk2 = error "Syntax Error at:"++(show p) 

Haskell не поддерживает анонимные конструктор (т.е. с помощью подчеркивания для сопоставления с образцом любого конструктора), даже если все конструкторы типа данных имеют одни и те же элементы.

Вы можете использовать поле записи в вашем типе данных, это будет автоматически создать функцию доступа:

data Token = THEN { src_pos :: AlexPosn } 
      | ELSE { src_pos :: AlexPosn } 

Это создает функцию src_pos, которую можно использовать, как и любую другую функцию:

eat_token tok ts2 = error "Syntax Error at: " ++ (show (src_pos tok)) 

По как Alex (и Happy) не особенно дружелюбны к новичкам. В настоящее время большинство пользователей используют Parsec/Attoparsec. С Parsec вы пишете синтаксический код в Haskell, а не препроцессором.