2015-11-01 47 views
2

Когда вы пишете описание Happy, вам нужно определить все возможные типы токенов, которые могут появиться. Но вы можете сопоставить только с символическими типов, а не отдельные лексемы значения ...Happy: Это не ключевое слово

Это своего рода проблематично. Рассмотрим, например, ключевое слово data. Согласно отчету Haskell, этот токен является «зарезервированным». Поэтому мой токенизатор распознает его и отмечает его как таковой. Однако рассмотрите ключевое слово as. Теперь выясняется, что это не a reservedid; это обычный вариант. Это только одно в одном контексте. Вы можете полностью объявить нормальную переменную с именем as, и все в порядке.

Итак, вот вопрос: Как разобрать as?

Первоначально я действительно не думал об этом. Я просто определил новый тип токена, который представляет любой токен varid, у которого текст as.

... а затем я провел около 2 часов, пытаясь выработать почему ад моя грамматика на самом деле не работает. Да, получается, что, поскольку этот тип токена перекрывается с существующим типом токена, порядок объявления является значительным. (!!!) Буквально, изменение порядка заявлений делало грамматику синтаксически безупречной.

Но теперь я волнуюсь. Я боюсь, что as никогда не будет сопоставляться как varid и будет соответствовать только самому себе. Таким образом, все правила грамматики, которые говорят varid, отклонят токен as —, что совершенно неправильно!

Что такое правильно Способ исправить это?

ответ

5

Что GHC делает в своей Parser.y является определением нетерминального типа маркеров special_id, который перечисляет многие из специальных, не являющихся ключевых слов, как as, а затем определить tyvarid и varid (нетерминал) лексему включить, что в качестве опции кроме терминала VARID (и некоторые другие, хотя большинство из них смотрят на меня так, как будто они должны тоже были поставлены в special_id).

Отрывок:

varid :: { Located RdrName } 
     : VARID   { sL1 $1 $! mkUnqual varName (getVARID $1) } 
     | special_id  { sL1 $1 $! mkUnqual varName (unLoc $1) } 
     | 'unsafe'   { sL1 $1 $! mkUnqual varName (fsLit "unsafe") } 
     ... 

special_id :: { Located FastString } 
special_id 
     : 'as'     { sL1 $1 (fsLit "as") } 
     | 'qualified'   { sL1 $1 (fsLit "qualified") } 
     | 'hiding'    { sL1 $1 (fsLit "hiding") } 
     | 'export'    { sL1 $1 (fsLit "export") } 
     ... 

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

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