Как сохранить несколько семантических значений при разборе с Happy / Haskell - PullRequest
4 голосов
/ 24 июля 2010

Я пытаюсь создать простой лексер / парсер с помощью Alex / Happy в Haskell, и я хотел бы сохранить некоторую информацию о локализации из текстового файла в моем окончательном AST.

Мне удалось построитьиспользуя лексера Alex, который создает список токенов с локализацией:

data Token = Token AlexPosn Foo Bar
lexer :: String -> [Token]

в моем файле Happy, при объявлении части токена% я могу объявить семантическую часть токена с символом $$

%token FOO  { Token _ $$ _ }

и в правиле разбора $ i будет ссылаться на этот $$.

foo_list: FOO  { [$1] }
        | foo_list FOO { $2 : $1 }

Есть ли способ сослаться на часть AlexPosn и к Foo-части токена FOO?Прямо сейчас я знаю только, как относиться только к одному из них.Я могу найти информацию о способе «добавить несколько $$» и обратиться к ним впоследствии.

Есть ли способ сделать это?

V.

Ответы [ 2 ]

4 голосов
/ 28 июля 2010

В итоге я нашел 2 решения:

  • упакуйте все значащие данные в кортеж, чтобы $$ указывал на этот кортеж, а затем извлекал данные по проекции:

    data Token = Token (AlexPosn,Foo) Bar
    %token FOO { Token $$ some_bar }
    rule : FOO  { Ast (fst $1) (snd $1) }
    
  • вообще не используйте $$: если вы не используете $$, happy предоставит вам полный токен во время синтаксического анализа, так что вы можете извлечь из этого токена то, что вам действительно нужно:

    data Token = Token AlexPosn Foo Bar
    %token FOO = { Token _ _ some_bar }
    rule : FOO  { Ast (get_pos $1) (get_foo $1) }
    
    get_pos :: Token -> AlexPosn
    get_foo :: Token -> Foo
    

    ...

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

0 голосов
/ 20 апреля 2018

Также возможно сохранить несколько значений, например:

data Token = Token AlexPosn Foo Bar
%token FOO { Token pos foo some_bar }
rule : FOO { Ast pos foo }

Хотя я не уверен, что Happy действительно гарантирует, что это всегда будет работать.Причина того, почему это (возможно) работает, состоит в том, что happy сгенерирует код, соответствующий шаблону на Token pos foo some_bar, делая pos и foo доступными в Ast pos foo.

...