2016-03-28 13 views
0

Ich sah mir die Antlr v4 Grammatik an. Speziell das Java-Beispiel.ANTLR4 Validierung benutzerdefinierter Typen stimmen überein

https://github.com/antlr/grammars-v4/blob/master/java/Java.g4

bemerkte ich, dass die folgende Eingabe der bereitgestellten Grammatik gültig ist.

Offensichtlich wissen wir alle, dass dies keine gültige Aussage in Java ist. Wie in Antlr4 machen Sie dies ungültig und werfen einen Fehler? Ich vermute, Sie tun es in den von BaseVisitor generierten Funktionen, aber ich habe Mühe, ein Beispiel im Antlr4-Buch oder online zu finden.

+0

Parser (das Ergebnis von Parsergeneratoren) tun dies einfach nicht. Sie verarbeiten nur Parsing und reichen bei weitem nicht aus, um ein echtes Programm zu analysieren. Siehe meinen Essay über "Life After Parsing" (über meine Biografie oder einfach googlen). –

Antwort

1

Je nach dem spezifischen Compiler wird dies in der kontextuellen Analyse/Typchecking - in der Walkthrough des Parse Baumes getan. Es wird getan, indem der Baum mit Arten "geschmückt" wird. Dies würde "String" als einen Typ auf die "Hallo Welt" setzen! Knoten und "float" auf dem Deklarationsknoten. Der Compiler wäre dann in der Lage, den Fehler zu erkennen und eine Fehlermeldung zu geben.

Ja, es ist mit den Besuchern mit ANTLR getan. Sie können die BaseVisitor-Klasse erweitern, um eigene Besuchermethoden zu erstellen, in denen Sie die Deko- und Typprüfung durchführen. Ein Beispiel unter von einem meiner eigenen Projekte:

@Override 
public Node visitEqCond(EqCondNode node){ 
    CondNode left = (CondNode) visit(node.left); 
    CondNode right = (CondNode) visit(node.right); 

    if(left.type.equals("num") && right.type.equals("num") && left.typeCorrect && right.typeCorrect){ 
     node.type = "bool"; 
    } 
    else{ 
     node.typeCorrect = false; 
     if(!left.type.equals("num")){ 
      err.TypeNotApplicableInOperationError(left.type, node.operator, node.lineNumber); 
     } 
     if(!right.type.equals("num")){ 
      err.TypeNotApplicableInOperationError(right.type, node.operator, node.lineNumber); 
     } 
    } 
    return node; 
} 

Offensichtlich ist dies erfordert, dass Sie Ihre eigenen Knoten mit dem „Typ“ geschaffen haben und „typeCorrect“ zuschreibt. Konkret ist diese Methode ziemlich einfach. Wenn Sie einen bestimmten Ausdruck aufrufen, legen Sie den Typ abhängig davon fest, welchen Typ Sie dort haben. Ein Ausdruck wäre beispielsweise der "hello world" Teil der Zuweisung in Ihrem Beispiel. Wenn ich den spezifischen Knoten besuche (sagen wir StringExpr), setze ich das "type" -Attribut auf String, und ich mache dasselbe für den Zuweisungsknoten, den ich auf "Float" setze. Ich kann dann sehen, dass die Zuordnung und Ausdruck nicht übereinstimmt, und kann einen Fehler auslösen.

0

Sie können es durch Verwendung semantischer Prädikate tun. Schauen Sie sich diesen Artikel an: What is a 'semantic predicate' in ANTLR?

+0

In der Praxis können Sie das nicht tun. Erstens sind die von der Semantik benötigten Informationen möglicherweise noch nicht verfügbar (was ist, wenn diese Information eine Forward-Referenz ist?). Zweitens sind die Typkompatibilitätsüberprüfungen für echte Sprachen sehr komplex; Sie neigen nicht dazu, in Prädikate zu gleiten, die Sie als Tests implementieren können, die während der Analysereduktion ausgeführt werden. (Sie können mir gerne ein Frontend für eine auf diese Weise realisierte Produktionssprache zeigen.) –