ich eine Grammatik, die den folgenden Code-Schnipsel (als Beispiel) analysieren soll:Handhabung Grammar Mehrdeutigkeit in ANTLR4
vmthread programm_start
{
CALL main
}
subcall main
{
// Declarations
DATAF i
CALL i
// Statements
MOVEF_F 3 i
}
Das Problem ist die Mehrdeutigkeit zwischen der CALL-Anweisung. Dieser Op-Code ist im vmthread-Abschnitt (und nur in CALL!) Gültig, aber auch in diesen Unterabschnitten. Wenn ich ein OP_CODES-Token mit allen Op-Codes und einem zusätzlichen OC_CALL-Token definiere, kann der Lexer (offensichtlich) nicht mit der Situation umgehen.
Die folgenden Auflistungen sind Auszüge, meine Grammatik (erste Lexer, zweiter Parser):
VMTHREAD
: 'vmthread'
;
SUBCALL
: 'subcall'
;
CURLY_OPEN
: '{'
;
CURLY_CLOSE
: '}'
;
OP_CODES
: 'DATA8'
| 'DATAF'
| 'MOVE8_8'
| 'MOVEF_F'
| 'CALL'
;
OC_CALL
: 'CALL'
;
lms
: vmthread subcalls+
;
vmthread
: VMTHREAD name = ID CURLY_OPEN vmthreadCall CURLY_CLOSE
;
vmthreadCall
: oc = OC_CALL name = ID
;
subcalls
: SUBCALL name = ID CURLY_OPEN ins = instruction* CURLY_CLOSE
;
//instruction+
instruction
: oc = OP_CODES args = argumentList
;
argumentList
: arguments+
;
arguments
: INTEGER
| NUMBER
| TEXT
| ID
;
meine Arbeit fortzusetzen Ich habe Token die OC_CALL Token in der vmthreadCall Parser-Regel mit dem OP_CODES geschaltet. Das löst das Problem jetzt, da der Code automatisch generiert wird. Aber es gibt die Möglichkeit, dass ein Benutzer diesen Code eingeben kann, damit dies schief gehen kann.
Gibt es eine Lösung dafür oder sollte ich die Validierung in den Parser verschieben. Dort kann ich leicht feststellen, ob die Anweisung im vmthread-Abschnitt nur die Aufrufanweisung enthält.
Zur Verdeutlichung: Im vmthread ist nur die CALL erlaubt. In der Unterklasse (könnte mehr als eine sein) ist jeder Op-Code erlaubt (CALL + jeder andere Op-Code definiert). Und ich möchte nicht zwischen diesen verschiedenen CALL-Anweisungen unterscheiden. Ich weiß, dass das in einer kontextfreien Grammatik nicht möglich ist. Ich werde das im Parser behandeln. Ich möchte nur den vmthread auf die eine CALL-Anweisung beschränken und alle Anweisungen (alle Op-Codes) in den Unteralls zulassen. Hoffentlich ist das klarer.
Ihre Frage ist unklar, weil Sie uns die * beabsichtigten * Regeln nicht gesagt haben, nur dass Sie eine Grammatik produziert haben, die Ihrer Meinung nach den Absichten entspricht. Ist "CALL" in beiden Unterprogrammen erlaubt? Versuchen Sie, einen Aufruf im vmthread von dem Aufruf im Unterordner zu unterscheiden? (Sie können das nicht in einer kontextfreien Grammatik [wie ANTLR]). –
@IraBaxter Ich schrieb einen Text zur Verdeutlichung ("CALL" ist in beiden Subroutinen erlaubt und ich möchte die verschiedenen CALLs nicht unterscheiden). – FDeitelhoff
OK. Sie sagten, CALL sei zweideutig. Was sind deine Beweise? –