BlitzBasic Syntax
Übersicht

![]() |
VertexBetreff: BlitzBasic Syntax |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hey,
lese gerade "Visionäre der Programmierung" (Interviews mit den Autoren von BASIC, Java, UML, C# usw.) und das hat mich mal wieder beflügelt mich mit BlitzBasic auseinander zu setzen. Die Idee von diesem Thread ist, die Syntax von BlitzBasic nieder zu schreiben ![]() ![]() ![]() Wie ich finde, ist BlitzBasic eine hervorragende Lehrsprache. Das Problem ist bloß, dass BlitzBasic kommerziell vertrieben wird, weshalb es für Schulen und Unis nicht geeignet ist. Für die Unis im Bereich der theoretischen Informatik, die sich auch mit Sprachen und Compilerbau beschäftigt, fehlt eine Syntaxbeschriebung von BB ebenfalls. Wir haben bspw. mit Pascal angefangen zu programmieren und haben dann in der theoretischen Informatik EBNF anhand von Pascal besprochen. Gleiches würde ich mir mit BB wünschen. Ein bischen Theorie zu Sprachen angewandt auf BB, damit man die richtigen Begriffe bei den Diskussionen verwenden kann: ![]() ![]() ![]() Sprachen können endlich viele oder unendlich viele Wörter enthalten. Endliche Sprachen lassen sich durch Aufzählen ihrer Wörter beschreiben. Die Sprache BB kann jedoch unendlich viele Wörter enthalten: "Print 1", "Print 1 : Print 2", "Print 1 : Print 2 : Print 3", ... sind alles Wörter und von denen gibt es unendlich viele in BB. Um eine unendliche Sprache wie BB beschreiben zu können, benötigt man eine endliche Beschreibung. Das ist nur möglich, wenn die Sprache nach gewissen Regeln aufgebaut ist. Die Menge dieser Regeln wird als Syntax der Sprache bezeichnet; sie ist eine endliche Beschreibung der Sprache. Definition Syntax: Die Syntax einer Programmiersprache ist die Gesamtheit der Regeln, die angeben, was ein Programm ist. Definition Semantik: Die Semantik einer Programmiersprache ist die Gesamtheit der Regeln, die angeben, was ein Programm tut [Hans Werner Lang: Algorithmen in Java] Man unterscheidet bei der Semantik zwischen statischer und operationaler Semantik. Zwei typische Regeln für ersteres ist, dass Funktionen deklariert sein müssen, bevor man sie auffruft und der Typ auf der linken Seite einer Zuweisung der selbe sein muss wie der Typ auf der rechten Seite (bspw. x = 10 + 5: links int und rechts int). Zweiteres ist die eigentliche Semantik, die vorgibt, wie ein Sprachkonstrukt sich verhält. Beispielsweise dass erst der Else-Block ausgeführt wird, wenn der ausgewertete Ausdruck der If-Anweisung und aller ElseIf-Blöcke false ergibt. Folgendes Dokument fasst ausschließlich die Syntaxregeln von BB zusammen: Code: [AUSKLAPPEN] -- Autor: Oliver Skawronek
-- Version: 1.02 -- Änderungen: -- - Vertex 1.02: -- - SIMPLE_TYPED_IDENTIFIER ::= IDENTIFIER (SIMPLE_PREFIX)? -- wurde geändert in IDENTIFIER (SIMPLE_TYPE_PREFIX)? -- - NULL_LITERAL := 'Null' -- wurde geändert in NULL_LITERAL ::= 'Null' -- - Noobody 1.01: -- - HEX_LITERAL ::= '$' ('0'..'9' | 'A'..'B' | 'a'..'b')+ -- wurde geändert in '$' ('0'..'9' | 'A'..'F' | 'a'..'f')+ -- - SingleLineIfStatement das ('End If' | 'EndIf') -- wurde geändert in ('End If' | 'EndIf')? -- Parser Main ::= (MainSegment)* Block ::= (BlockSegment)* MainSegment ::= BlockSegment | DataDirective | ConstantsDeclaration | GlobalArraysDeclaration | TypeDeclaration | FunctionDelcaration BlockSegment ::= IncludeDirective | GlobalvariablesDeclaration | LocalVariablesDeclaration | LabelDeclaration | Statement Statement ::= RestoreStatement | ReadStatement | GotoStatement | GosubStatement | IfStatement | SelectStatement | ReturnStatement | ExitStatement | WhileStatement | RepeatStatement | ForStatement | ForEachStatement | AssignmentStatement | CallStatement | InsertStatement | DeleteStatement | DeleteEachStatement -- Direktiven IncludeDirective ::= 'Include' STRING_LITERAL DataDirective ::= 'Data' Expression (',' Expression)* -- Konstanten ConstantsDeclaration ::= 'Const' ConstantDeclaration (',' ConstantDeclaration)* ConstantDeclaration ::= SIMPLE_TYPED_IDENTIFIER '=' Expression -- Variablen und Arrays GlobalvariablesDeclaration ::= 'Global' VariableDeclaration (',' VariableDeclaration)* LocalVariablesDeclaration ::= 'Local' VariableDeclaration (',' VariableDeclaration)* VariableDeclaration ::= LocalArrayDeclaration | TYPED_IDENTIFIER '=' Expression LocalArrayDeclaration ::= IDENTIFIER '[' Expression ']' GlobalArraysDeclaration ::= 'Dim' GlobalArrayDeclaration (',' GlobalArrayDeclaration)* GlobalArrayDeclaration ::= TYPED_IDENTIFIER '(' Expression (',' Expression)* ')' -- Blitz-Bezeichner BlitzIdentifier ::= BlitzIdentifierSegment ('\' BlitzIdentifierSegment)* BlitzIdentifierSegment ::= TYPED_IDENTIFIER (GlobalArrayAccess | LocalArrayAccess)? GlobalArrayAccess ::= '(' Expression (',' Expression)* ')' LocalArrayAccess ::= '[' Expression ']' -- Sprungmarke LabelDeclaration ::= '.' IDENTIFIER -- Type TypeDeclaration ::= 'Type' IDENTIFIER (FieldDeclaration)* 'End Type' FieldDeclaration ::= 'Field' TYPED_IDENTIFIER -- Funktion FunctionDelcaration ::= 'Function' TYPED_IDENTIFIER '(' (Parameter (',' Parameter)*)? ')' (Statement)* 'End Function' Parameter ::= SIMPLE_TYPED_IDENTIFIER ('=' Expression)? | TYPED_IDENTIFIER -- Data RestoreStatement ::= 'Restore' (IDENTIFIER)? ReadStatement ::= 'Read' BlitzIdentifier -- Goto- und Gosub-Anweisungen GotoStatement ::= 'Goto' IDENTIFIER GosubStatement ::= 'Gosub' IDENTIFIER -- Bedingte Anweisung IfStatement ::= BlockIfStatement | SingleLineIfStatement BlockIfStatement ::= 'If' Expression ('Then')? NEW_LINE (ElseIfBlock)* (ElseBlock)? ('End If' | 'EndIf') SingleLineIfStatement ::= 'If' Expression ('Then')? (ElseIfBlock)* (ElseBlock)? ('End If' | 'EndIf')? ElseIfBlock ::= ('ElseIf' | 'Else If') Expression ('Then')? Block ElseBlock ::= ('Else') Block -- Mehrseitige Auswahl SelectStatement ::= 'Select' Expression (CaseBlock)* (DefaultBlock)? 'End Select' CaseBlock ::= 'Case' Expression (',' Expression)* Block DefaultBlock ::= 'Default' Block -- Return-Anweisung ReturnStatement ::= 'Return' (Expression)? -- Funktionsaufruf CallStatement ::= IDENTIFIER ('(' (Expression (',' Expression)*)? ')')? -- Schleifen ExitStatement ::= 'Exit' WhileStatement ::= 'While' Expression Block 'Wend' RepeatStatement ::= 'Repeat' Block 'Until' Expression ForStatement ::= 'For' AssignmentStatement 'To' Expression (StepExpression)? Block 'Next' StepExpression ::= 'Step' Expression ForEachStatement ::= 'For' BlitzIdentifier '=' 'Each' IDENTIFIER Block 'Next' -- Zuweisung AssignmentStatement ::= BlitzIdentifier '=' (Expression | ListExpression) -- Listenbefehle InsertStatement ::= 'Insert' (BlitzIdentifier | '(' BlitzIdentifier ')') (BeforeExpression | AfterExpression) DeleteStatement ::= 'Delete' ListExpression DeleteEachStatement ::= 'Delete' 'Each' IDENTIFIER -- Listenausdruck ListExpression ::= BlitzIdentifier | BeforeExpression | AfterExpression | FirstExpression | LastExpression BeforeExpression ::= 'Before' (ListExpression | '(' ListExpression ')') AfterExpression ::= 'After' (ListExpression | '(' ListExpression ')') FirstExpression ::= 'First' IDENTIFIER LastExpression ::= 'Last' IDENTIFIER -- Ausdruck Expression ::= ('Not')? BitExpression BitExpression ::= RelationExpression (('And' | 'Or' | 'Xor') RelationExpression)* RelationExpression ::= AddExpression (('=' | '<>' | '><' | '<' | '<=' | '=<' | '>' | '>=' | '=>') AddExpression)* AddExpression ::= ShiftExpression (('+' | '-') ShiftExpression)* ShiftExpression ::= Term (('Shl' | 'Shr' |'Sar') Term)* Term ::= Power (('*' | '/' | 'Mod') Power)* Power ::= Unary ('^' Unary)* Unary ::= ('~')? Factor ('~' Factor)* Factor ::= INTEGER_LITERAL | FLOAT_LITERAL | STRING_LITERAL | NULL_LITERAL | '(' Expression ')' | TypeInstance | TypeCast | FunctionCall | BlitzIdentifier TypeInstance ::= 'New' IDENTIFIER TypeCast ::= 'Int' '(' Expression ')' | 'Float' '(' Expression ')' | 'Str' '(' Expression ')' FunctionCall ::= IDENTIFIER '(' (Expression (',' Expression)*)? ')' -- Lexer COMMENT ::= ';' (~('\n' | '\r'))* NEW_LINE IDENTIFIER ::= ('A'..'Z' | 'a'..'z') ('A'..'Z' | 'a'..'z' | '0'..'9' | '_')* SIMPLE_TYPED_IDENTIFIER ::= IDENTIFIER (SIMPLE_PREFIX)? TYPED_IDENTIFIER ::= IDENTIFIER (TYPE_PREFIX)? TYPE_PREFIX ::= SIMPLE_TYPE_PREFIX | '.' IDENTIFIER SIMPLE_TYPE_PREFIX ::= '%' | '#' | '$' NULL_LITERAL ::= 'Null' INTEGER_LITERAL ::= DECIMAL_LITERAL | HEX_LITERAL | BIN_LITERAL DECIMAL_LITERAL ::= ('0'..'9')+ HEX_LITERAL ::= '$' ('0'..'9' | 'A'..'F' | 'a'..'f')+ BIN_LITERAL ::= '%' ('0' | '1')+ FLOAT_LITERAL ::= ('0'..'9')* '.' ('0'..'9')+ STRING_LITERAL ::= ('\"') (~('\"' | '\n' | '\r'))* ('\"') NEW_LINE ::= '\n' | '\r' ('\n')? WHITESPACE ::= '\t'..'\n' | ' ' | ' : ' Sie wurden aus meiner Erfahrung mit BB erstellt und teilweise mit dem BB-Compiler immer wieder überprüft. Mein Anliegen wäre es, dass ihr nach Beispielen sucht, wo diese Syntax versagt. Das heißt der BB-Compiler akzeptiert die Eingabe/den Quelltext und die hier angegebene Syntax nicht. Hinweis zu WHITESPACE: Whitespaces sind hier Chr$(9) .. Chr$(13) das Leerzeichen und der Doppelpunkt. Was ist eurer Meinung nach die Aufgabe des Doppelpunkts? Doppelpunkt=New Line oder Trenner von Anweisungen? Akuell würde die Syntax folgendes Wort nicht akzeptieren: "If True Then Print 123:Else Print 456" der BB-Compiler schon. Definiere ich allerdings WHITESPACE ::= '\t'..'\n' | ' ' | " : " so, dann würde auch "Print(:123: ![]() Ein Beispiel zum Anwenden der Syntax: BlitzBasic: [AUSKLAPPEN] Type TPerson Das Beispiel würde folgenden Parse-Tree erzeugen: Code: [AUSKLAPPEN] Main {
// Type TPerson .. End Type MainSegment->TypeDeclaration { 'Type' IDENTIFIER := 'TPerson' // Field Name$ FieldDelcaration { 'Field' TYPED_IDENTFIER := 'Name$' } 'End Type' } // Local Person.TPerson = New TPerson MainSegment->BlockSegment->LocalVariablesDeclaration { 'Local' VariableDeclaration { TYPED_IDENTIFIER := 'Person.TPerson' '=' Expression->BitExpression->RelationExpression->AddExpression ->ShiftExpression->Term->Power->Unary->Factor->TypeInstance { 'New' IDENTIFIER := 'TPerson' } } } // Person\Name$ = "Max" MainSegment->BlockSegment->Statement->AssignmentStatement { BlitzIdentifier { BlitzIdentifierSegment { TYPED_IDENTIFIER := 'Person' } '\' BlitzIdentifierSegment { TYPED_IDENTIFIER := 'Name$' } } '=' Expression->BitExpression->RelationExpression->AddExpression ->ShiftExpression->Term->Power->Unary->Factor { STRING_LITERAL = '"Max"' } } // For P = Each TPerson .. Next MainSegment->BlockSegment->Statement->ForEachStatement { BlitzIdentifier { TYPED_IDENTIFIER := 'P' } '=' 'Each' IDENTIFIER := 'TPerson' Block { // Print P\Name$ BlockSegement->CallStatement { IDENTIFIER := 'Print' Expression->BitExpression->RelationExpression->AddExpression ->ShiftExpression->Term->Power->Unary->Factor { BlitzIdentifier { BlitzIdentifierSegment { TYPED_IDENTIFIER := 'P' } '\' BlitzIdentifierSegment { TYPED_IDENTIFIER := 'Name$' } } } } } 'Next' } // WaitKey MainSegment->BlockSegement->CallStatement { IDENTIFIER := 'Waitkey' } } Ciao Olli |
||
- Zuletzt bearbeitet von Vertex am Do, Jul 22, 2010 10:53, insgesamt 5-mal bearbeitet
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
Soweit ich mir erinnere, gehen die Hexziffern von 1-F und nicht von 1-B ![]() Ansonsten fallen mir beim überfliegen hie und da auch noch andere Ungereimtheiten auf (zum Beispiel ist beim einzeiligen If das EndIf optional). Vor allem stellt sich mir aber die Frage, wofür man so etwas braucht - du sagst zwar, dass für die Uni so etwas nützlich wäre, aber BB ist nun wirklich keine Sprache mit schöner Syntax und daher auch nicht wirklich sinnvoll, wenn man sie in theoretischer Informatik betrachtet. Und für Compilerbauer? Ich weiss ja nicht, aber wenn man ein wenig mit BB gearbeitet hat, nützt einem das Gedächtnis fast mehr als ein verwirrendes Stück EBNF (nichts gegen deinen Schreibstil, aber theoretisches Zeug wie die (E)BNF wird bei komplexeren Beispielen als 'ABBABBABBABB' schlichtweg unleserlich). |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke, habe ich geändert.
Also EBNF (das hier ist EBNF und nicht BNF) ist nicht nur eine Beschreibungssprache für Akademiker, sondern sie wird als Referenz für bekannte Programmiersprachen genutzt. Siehe Java (Kapitel 18 auf Seite 585), C# (Annex A. Grammar, Seite 443) oder Python um nur drei zu nennen. Heutzutage gibt es gute Tools zum Entwickeln von Sprachen: ANTLR oder Xtext. Mit letzterem erstellt man eine Grammatik in EBNF und Xtext generiert daraus einen vollfunktionsfähigen Eclipse-Editor mit Syntax-Highlighting, Code-Completion, Quick-Assist, Outline-View, Problems-View usw. Das ist aber hier nicht primär das Ziel des Topics diese Tools zu nutzen, sondern nur eine Syntax-Beschreibung von BB zu erstellen. Ciao Olli Edit: Die obige Syntax lässt sich noch nicht ohne weiteres als ANTLR-Grammatik umsetzen, da einige Regeln noch mehrdeutig sind. Aber ich habe mal eine vereinfachte Variante erstellt und den Parse-Tree für ein simples Beispiel generiert: BlitzBasic: [AUSKLAPPEN] Dim MyArrayA(10), MyArrayB(10) |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group