Лексировать новые строки в Scala StdLexical? - PullRequest
3 голосов
/ 14 апреля 2010

Я пытаюсь лексировать (затем анализировать) язык, подобный Си. В Си есть директивы препроцессора, где разрывы строк значительны, а затем фактический код, где они просто пробелы.

Одним из способов сделать это может быть двухпроходный процесс, подобный ранним компиляторам C - иметь отдельный препроцессор для директив #, а затем преобразовать его в лекс.

Однако мне стало интересно, возможно ли сделать это в одном лексере. Я очень доволен написанием кода парсера-комбинатора scala, но я не совсем уверен, как StdLexical обрабатывает пробелы.

Может ли кто-нибудь написать какой-нибудь простой пример кода, который скажет, может ли лексировать строку #include (с использованием новой строки) и какой-нибудь тривиальный код (игнорируя новую строку)? Или это невозможно, и лучше использовать двухпроцессный appproach?

1 Ответ

7 голосов
/ 14 апреля 2010

ОК, решил сам, отвечу за потомство.

В StdLexical у вас уже есть возможность указывать пробелы в лексере. Все, что вам нужно сделать, это переопределить ваш метод токена соответствующим образом. Вот пример кода (с удаленными несущественными битами)

override def token: CeeLexer.Parser[Token] = controlLine 
  // | ... (where ... is whatever you want to keep of the original method)
def controlLine = hashInclude

def hashInclude : CeeLexer.Parser[HashInclude] =
  ('#' ~ word("include") ~ rep(nonEolws)~'\"' ~ rep(chrExcept('\"', '\n', EofCh)) ~ '\"' ~ '\n' |
   '#' ~ word("include") ~ rep(nonEolws)~'<' ~ rep(chrExcept('>', '\n', EofCh)) ~ '>' ~ '\n' ) ^^ {
   case hash~include~whs~openQ~fname~closeQ~eol =>  // code to handle #include
 }
...