Lexing Zeilenumbrüche in scala StdLexical?
-
26-09-2019 - |
Frage
Ich versuche (parsen dann) lex eine C ähnliche Sprache. In C gibt es Präprozessordirektiven wo Zeilenumbrüche von Bedeutung sind, dann ist der eigentliche Code, wo sie sind nur Leerzeichen.
Eine Möglichkeit, dies zu tun, einen zwei Pass Prozess wie frühe C-Compiler tun würde -. Hat einen separaten Preprozessor für die # Direktiven, dann die Ausgabe, dass lex
Allerdings habe ich mich gefragt, ob es möglich war, sie in einem einzigen Lexer zu tun. Ich bin ziemlich glücklich mit dem scala-Parser-Kombinator Code zu schreiben, aber ich bin nicht so sicher, wie StdLexical
Griffe Leerzeichen.
Könnte jemand schreiben einige einfache Beispielcode, der eine #include
Linie lex sagen konnte (die Neue-Zeile verwendet wird) und einige triviale Code (die Neue-Zeile ignoriert wird)? Oder ist dies nicht möglich, und es ist besser zu gehen mit dem 2-Pass appproach?
Lösung
OK, löste dies mir Antwort hier für die Nachwelt.
In StdLexical Sie haben bereits die Möglichkeit, Leerzeichen in Ihrem Lexer angeben. Alles, was Sie tun müssen, ist Ihr Token-Verfahren in geeigneter Weise außer Kraft setzen. Hier ist ein Beispielcode (mit nicht relevanten Bits entfernt)
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
}