2016-01-05 12 views
7

Ich habe eine .g4-Grammatik für / ein Lexer/Parser, wo der Lexer Zeilenfortsetzungs-Token überspringen - nicht überspringen sie bricht den Parser und ist keine Option. Hier ist die Lexer Regel in Frage:Unerledigter Code bricht meine Grammatik

LINE_CONTINUATION : ' ' '_' '\r'? '\n' -> skip; 

Das Problem dieser verursacht wird, das heißt, wenn eine fortgesetzte Linie beginnt in Spalte 1, der Parser sprengt:

Sub Test() 
Debug.Print "Some text " & _ 
vbNewLine & "Some more text"  
End Sub 

Ich dachte: „Hey ich weiß! Ich werde nur die Zeichenfolge, die ich ANTLR füttere, vorprozessieren, um vor dem Unterstrich einen zusätzlichen Leerraum einzufügen und die Grammatik zu ändern, um sie zu akzeptieren! "

Also änderte ich die Regel wie folgt aus:

LINE_CONTINUATION : WS? WS '_' NEWLINE -> skip; 
NEWLINE : WS? ('\r'? '\n') WS?; 
WS : [ \t]+; 

... und der Test Code gab mir über diesen Parser-Fehler:

extraneous input 'vbNewLine' expecting WS

Denn jetzt meine einzige Lösung zu sagen, ist mein Benutzer ihren Code richtig einzurücken. Kann ich diese Grammatikregel irgendwie korrigieren?

(Full VBA.g4 grammar file on GitHub)

+0

Warum verschmelzen Sie LINE_CONTINUATION in WS? –

+0

@IraBaxter 'WS' wird in vielen anderen Orten verwendet. Was meinen Sie? –

+1

Grundsätzlich möchten Sie, dass die Zeilenfortsetzung wie Leerzeichen behandelt wird. OK, dann fügen Sie dem WS-Token die lexikalische Definition der Zeilenfortsetzung hinzu. –

Antwort

4

Sie wollen im Grunde Zu wie Leerzeichen behandelt werden.

OK, dann fügen Sie dem WS-Token die lexikalische Definition der Zeilenfortsetzung hinzu. Dann wird WS die Zeilenfortsetzung übernehmen, und Sie brauchen die LINECONTINUATION nirgends.

//LINE_CONTINUATION : ' ' '_' '\r'? '\n' -> skip; 
NEWLINE : WS? ('\r'? '\n') WS?; 
WS : ([ \t]+)|(' ' '_' '\r'? '\n'); 
+0

Ich werde verdammt sein. Es funktionierte! –

+0

Speichen zu schnell. Es hat geklappt ... * für den speziellen Fall im OP * - also habe ich versucht, die 'WS'-Regel in 'WS zu ändern: [\ t] + (' _ '' \ r '?' \ N ') ?; ', und jetzt funktioniert es und unterstützt seltsame Dinge, wie' Option Base 1' in 'Option _ \ r \ nBase _ \ r \ n1' aufgeteilt wird, was großartig ist - aber es bricht jedes Mal, wenn eine fortgesetzte Zeile eine Einrückung hat und ich nicht verstehe nicht warum, da die Definition, wie ich sie verstehe, * auch * mit einem oder mehreren Leerzeichen/Tabs übereinstimmen sollte ... einen Hinweis bekommen? –

+1

Ich denke, ich hätte die Dinge anders definiert: HWS = [\ t \] +; ENDLINE = \ r? \ n; NEWLINE = HWS? ZIELLINIE; WS = HWS (ENDLINE HWS?)? ; Dieses letzte Bit reicht Ihre "fortgesetzte Zeile hat Einzug". Der Rest ist nur Faktorisieren, um es leichter zu verstehen. (HWS == "horizontaler Leerraum"). –