ich zahlreiche kleine Probleme gefunden, die ich in der Grammatik unten korrigiert haben.
- Keine EOF-Markierung
- nur eine Anweisung ausgeführt werden kann, so dass es
- Die @header Sache java grungui verursacht
program
erweitert läuft nicht
_
ein gültiger Variablenname ist, wahrscheinlich nicht, was Sie wollen .
'5' ist eine gültige linke Seite der Zuweisung. Also 5=6
ist eine gültige Anweisung, wieder, wahrscheinlich nicht das, was Sie wollen.
grammar Arithmetic;
program : stat+ EOF;
stat
: Left = VARIABLE Op = ASSIGMENT Right = expr # Assigment
;
expr
: '(' Exp = expr ')' # Parens
| MINUS Exp = expr # UnaryMinus
| Left = expr Op = (TIMES | DIV) Right = expr # MulDiv
| Left = expr Op = (PLUS | MINUS) Right = expr # AddSub
| (VARIABLE | CONSTANT) # Element
;
ASSIGMENT : '=' ;
PLUS : '+' ;
MINUS : '-' ;
TIMES : '*' ;
DIV : '/' ;
LPAREN : '(' ;
RPAREN : ')' ;
VARIABLE : LETTER+(LETTER|DIGIT|'_')* ;
CONSTANT : INTEGER ;
INTEGER : DIGIT+ ;
LETTER : ('a' .. 'z') | ('A' .. 'Z') ;
DIGIT : ('0' .. '9') ;
WS : [ \r\n\t] + -> skip ;
nun korrigiert, dass eine Menge lexing und "gute Form" Fragen. Die nächste Frage ist, was man zum Beispiel mit der Division durch Null tun soll.
Die Grammatik ist nicht der Ort, um solche Regeln durchzusetzen. Zum Beispiel ist 3/0 ein vollkommen legaler mathematischer Ausdruck. Es ist einfach so, bis ins Unendliche auszuwerten, und deshalb in einem Programm zu schützen. Ebenso sollten Sie spezielle Fälle wie diesen in Ihrem Code behandeln. Wenn Sie Ihr Besucher- oder Listener-Muster implementieren, wenn die rechte Seite des #MulDiv-Kontexts gleich Null ist, sollten Sie an dieser Stelle eingreifen. Die Grammatik ist kein Ort, um zu versuchen, solch komplizierte semantische und kontextsensitive Regeln zu implementieren.
Was wie eine if
Anweisung zu programmieren, werde ich Ihnen einen Blick geben auf sie, wie sie ich implementieren:
public override MuValue VisitIfstmt(LISBASICParser.IfstmtContext context)
{
LISBASICParser.Condition_blockContext[] conditions = context.condition_block();
bool evaluatedBlock = false;
foreach (LISBASICParser.Condition_blockContext condition in conditions)
{
MuValue evaluated = Visit(condition.expr());
if (evaluated.AsBoolean())
{
evaluatedBlock = true;
Visit(condition.stmt_block());
break;
}
}
if (!evaluatedBlock && context.stmt_block() != null)
{
Visit(context.stmt_block());
}
return MuValue.Void;
}
Zugegeben, das wahrscheinlich nicht viel Sinn aus dem Zusammenhang macht, aber der Rest versicherte, es funktioniert. Um dies in seinem vollen Kontext zu sehen, besuchen Sie bitte Bart Kiers für ein hervorragendes Beispiel für Grammatik und Implementierung.
Division durch Null tritt zur Laufzeit auf, nicht zur Kompilierzeit. Das ANTLR-System unterscheidet bereits zwischen Schlüsselwörtern und Identifikatoren. Deine Frage ergibt keinen Sinn. – EJP
Nun, ich kompiliere Ausdruck in VHDL-Code. Also muss ich VHDL Keywords loswerden wie - "abs", "Zugriff", "nach", "alias", "alle", "und", "Architektur", "Array", "behaupten", "Attribut" , "Beginne", "Block", "Körper" usw. Schlüsselwörter oben waren nur ein Beispiel, ich werde die Frage thnx bearbeiten. – Samuel