Лексировать новые строки в Scala StdLexical?
Я пытаюсь лексировать (затем анализировать) язык, подобный Си. В Си есть директивы препроцессора, где разрывы строк значительны, а затем реальный код, где они просто пробелы.
Одним из способов сделать это может быть двухпроходный процесс, подобный ранним компиляторам C - иметь отдельный препроцессор для директив #, а затем преобразовать его в лекс.
Однако мне стало интересно, возможно ли сделать это в одном лексере. Я очень доволен написанием кода парсера-комбинатора Scala, но я не уверен в том, как StdLexical
обрабатывает пробелы.
Может ли кто-нибудь написать простой пример кода, который может сказать #include
строка (с использованием новой строки) и некоторый тривиальный код (игнорируя новую строку)? Или это невозможно, и лучше использовать 2-проходный appproach?
1 ответ
ОК, решил сам, отвечу здесь для потомков.
В 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
}