ANTLR

Hej Alla!

ANTLR (ANother Tool for Language Recognition) är ett verktyg för att skapa parsergeneratorer.

Den befinner sig på version 4 vilket känns bra, att landa i version 1 kan emellanåt ha sina baksidor. Verktyget har också bra hjälpmedel och dokumentation.

Själva grammatik-filen har liknande syntax som Lex och YACC, men då dessa verktyg genererar C/C++ har ANTLR ett större utbud av parserspråk. Bland annat Java, C# och Python.

Intressant är att det finns ett repository på github med grammatikfiler för en mängd olika programspråk, däribland Oberon-07. Då vi redan sneglat lite på det innan som en möjligt språk att utgå ifrån, laddade vi hem dess grammatikfil och körde den igenom ANTLR.

Vi testade med följande Oberon-07 nonsensprogram:

MODULE MyModule;
IMPORT 
    Out;
VAR
    added:INTEGER;
    i,j:INTEGER;
PROCEDURE add(i1:INTEGER; i2:INTEGER):INTEGER;
BEGIN
    RETURN i1 + i2
END add;
BEGIN
    Out.String("Hello!");
    i := 32;
    j := add(i, 4);
    Out.Int(j);
END MyModule.

Emellertid så blev det problem med skanningen av tal. Talet 32 ovan tolkades som först 3 och sedan 2, vilket resulterade i syntaxfel då i := 3 2; inte är korrekt. Efter att ha ändrat en aning i grammatikfilen (igenkänning av tal flyttades från produktion till lexikal) så fungerade det som vi ville.

Vi valde att generera en C# parser (.net 7) och nedanstående program är det som kördes för att testa nonsensprogrammet ovan:

using Antlr4.Runtime;
using Antlr4.Runtime.Tree;
    string input = System.IO.File.ReadAllText(@".\oberonTest1.mod");	
    ICharStream stream = CharStreams.fromString(input);
    ITokenSource lexer = new oberonLexer(stream);
    ITokenStream tokens = new CommonTokenStream(lexer);
    oberonParser parser = new oberonParser(tokens);
	 parser.BuildParseTree = true;
    IParseTree tree = parser.module();
    System.Console.WriteLine( tree.ToStringTree(parser));

Utskriften från sista raden blir:

(module MODULE (ident MyModule) ; (importList IMPORT (import_ (ident Out)) ;) (declarationSequence VAR (variableDeclaration (identList (identdef (ident added))) : (type_ (qualident (ident INTEGER)))) ; (variableDeclaration (identList (identdef (ident i)) , (identdef (ident j))) : (type_ (qualident (ident INTEGER)))) ; (procedureDeclaration (procedureHeading PROCEDURE (identdef (ident add)) (formalParameters ( (fPSection (ident i1) : (formalType (qualident (ident INTEGER)))) ; (fPSection (ident i2) : (formalType (qualident (ident INTEGER)))) ) : (qualident (ident INTEGER)))) ; (procedureBody declarationSequence BEGIN (statementSequence statement) RETURN (expression (simpleExpression (term (factor (designator (qualident (ident i1))))) (addOperator +) (term (factor (designator (qualident (ident i2))))))) END) (ident add)) ;) BEGIN (statementSequence (statement (procedureCall (designator (qualident (ident Out) . (ident String))) (actualParameters ( (expList (expression (simpleExpression (term (factor "Hello!"))))) )))) ; (statement (assignment (designator (qualident (ident i))) := (expression (simpleExpression (term (factor (number (integer 32)))))))) ; (statement (assignment (designator (qualident (ident j))) := (expression (simpleExpression (term (factor (designator (qualident (ident add))) (actualParameters ( (expList (expression (simpleExpression (term (factor (designator (qualident (ident i))))))) , (expression (simpleExpression (term (factor (number (integer 4))))))) )))))))) ; (statement (procedureCall (designator (qualident (ident Out) . (ident Int)) (selector ( (qualident (ident j)) ))))) ; statement) END (ident MyModule) .)

Ljuv musik :)

Till nästa gång funderar vi troligen på det tänkta programspråket.

Som alltid, är det någon som vill vara med och skapa Aduba så är ni ypperligt välkomna oavsett kunskapsnivå. Det viktiga är att vi har kul tillsammans!

Föregående
Föregående

Oberon-07

Nästa
Nästa

Aduba