[BNF/LARL(1)/bison] de precedence wil niet goed

Pagina: 1
Acties:

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-09 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
stel ik heb de volgende (simpele) grammatica:

code:
1
2
3
4
5
6
expression
    : expression '.' expression
    | expression '(' expression ')'
    | constant
    | identifier
    ;


Alleen als ik nou a.b(c) parse, dan krijg ik deze boom:
code:
1
2
3
4
5
6
7
operator .
 |
 +- a
 +- function call
      |
      +- b
      +- c


offtopic:
grrr waarom zijn die edit boxjes niet meer monospaced |:(


terwijl dat natuurlijk dit moet zijn:
code:
1
2
3
4
5
6
7
function call
 |
 +- operator .
 |    |
 |    +- a
 |    +- b
 +- c



Alles goed en wel, gewoon even de precedence definieren in bison:
code:
1
2
3
4
5
6
7
8
9
10
%left FUNCCALL
%left '.'

%%
expression
    : expression '.' expression
    | expression '(' expression ')' %prec FUNCCALL
    | constant
    | identifier
    ;


alleen dat helpt dus niet! Hij verkiest nog altijd de function call boven de . operator

Weet iemand hoe ik dit op kan lossen?

.edit: oh misschien wel handig om erbij te vermelden dat die . operator natuurlijk bedoeld is voor member selection als in C++/java/<insert random semi-OO-taal> :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Volgens mij moet je grammatica iets anders. Een expressie kan wel een functiecall zijn, maar die bestaat uit vaststaande onderdelen, tenminste normaliter (:)). Met jouw grammatica kun je een functiecall omschrijven met een willekeurige expressie.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
level_one_binairy_operator
    = {greater}                 greater
    | {greater_or_equal}    greater_or_equal
    | {smaller}                 smaller
    | {smaller_or_equal}        smaller_or_equal
    | {equals}                  equals
    | {not_equals}              not_equals
    ;


level_two_binairy_operator
    = {add}         plus
    | {sub}     minus
    | {or}      or
    ;


level_three_binairy_operator
    = {multiply}    asterix
    | {divide}      solidus
    | {div}         div
    | {mod}         mod
    | {and}         and
    ;


unairy_operator
    = {not}     not
    | {neg}     minus
    ;


//=================================================================
//          Expression Stuff
//=================================================================

expression
    = {simple_expression}   simple_expression
    | {level_one_operator}  expression level_one_binairy_operator simple_expression
    ;



simple_expression
    = {term}                        term
    | {level_two_operator}  simple_expression  level_two_binairy_operator term
    ;


term
    = {signed_factor}               signed_factor
    | {level_three_operator}    term level_three_binairy_operator signed_factor
    ;


signed_factor
    = {object_factor}               object_factor
    | {unairy_operator}         unairy_operator signed_factor
    ;


object_factor
    = factor object_function*
    ;


factor
    = {constant}                constant
    | {unknown_constant}        unknown_constant
    | {list}                        list
    | {function}                P.function
    | {braced_expr}         l_par   expression r_par
    | {reference}               identifier
    ;


constant
    = {integer} integer_constant
    | {string}  string_constant
    | {boolean} boolean_constant
    | {real}    real_constant
    ;


unknown_constant
    = type question_mark
    ;


//=================================================================
//          Object Function / Function Stuff
//=================================================================

object_function
    = dot identifier object_function_parameter_list?
    ;


object_function_parameter_list
    = l_par expression_list? r_par
    ;

    
function
    = identifier l_par expression_list? r_par
    ;


expression_list
    = expression expression_list_tail*
    ;


expression_list_tail
    = comma expression
    ;


Ik denk dat je hier wel iets aan hebt ;)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-09 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Verwijderd schreef op 09 augustus 2002 @ 18:03:
Volgens mij moet je grammatica iets anders. Een expressie kan wel een functiecall zijn, maar die bestaat uit vaststaande onderdelen, tenminste normaliter (:)). Met jouw grammatica kun je een functiecall omschrijven met een willekeurige expressie.
Maar een functiecall kun je juist ook omschrijven met een willekeurige expressie
Ik bedoel, de functie die aangeroepen moet worden is het resultaat van een expressie

als je doet a.b, dan levert dat een functie op (mits b een methode is van a natuurlijk). Door de haakjes erachter te zetten roep je m vervolgens aan. Maar dit zou ook kunnen (niet in bovenstaande grammatica natuurlijk, maar de volledige zoals ik m gedefnieerd heb):

code:
1
2
method m = a.b;
int c = m (3);


het resultaat zou equivalent moeten zijn aan

code:
1
int c = a.b (3);

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-09 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Alarmnummer schreef op 09 augustus 2002 @ 18:08:
Ik denk dat je hier wel iets aan hebt ;)


tja maar dan moet ik mijn hele expression non-terminal aanpassen, terwijl de rest wel gewoon goed werkt... 't is alleen die functioncall (en array subscript overigens, maar das net zoiets) die niet wil

want waarom doet ie de precedence niet zoals ik aangeef?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

.oisyn schreef op 09 augustus 2002 @ 18:11:
[...]
Maar een functiecall kun je juist ook omschrijven met een willekeurige expressie
Ik bedoel, de functie die aangeroepen moet worden is het resultaat van een expressie
als je doet a.b, dan levert dat een functie op (mits b een methode is van a natuurlijk). Door de haakjes erachter te zetten roep je m vervolgens aan. Maar dit zou ook kunnen (niet in bovenstaande grammatica natuurlijk, maar de volledige zoals ik m gedefnieerd heb)
Ok, dat verandert de zaak natuurlijk.

Feit is wel dat van links naar rechts hij een operator '.' token tegenkomt en daarachter zich weer een expression bevindt, waardoor je een boom krijgt

code:
1
2
3
        .
        |
   expr   expr(expr)


en niet rond jouw functiecall.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-09 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Verwijderd schreef op 09 augustus 2002 @ 18:20:
[...]
en niet rond jouw functiecall.


klopt idd, maar dat is nou net een zaak die de precedence declarations aan moeten geven

als ik namelijk dit als grammatica opgeef:

code:
1
2
3
4
5
6
7
8
9
10
11
12
%left '+' '-'
%left '*' '/'

%%

expression
    : expression '+' expression
    | expression '-' expression
    | expression '*' expression
    | expression '/' expression
    | constant
    ;


en ik parse: 3 + 4 * 5 + 6

dan groupeert ie eerst 4 * 5, en daarna de 3, en daarna de 6. Je krijgt dus ((3) + ((4) * (5))) + (6)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Ja ok ik zat te slapen |:(.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-09 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
ja maar het is vrijdagavond, weekend dus, dan ga je toch niet slapen :? ;)

ennieweej, het komt waarschijnlijk door een shift/reduce conflict die die function call genereert.
Als je a.b (3) parset, en hij is bij 'b' en kijkt naar de '(', dan heeft ie 2 opties: een non-terminal maken van datgene wat ie op z'n stack heeft staan (zodat je een identifier als expressie krijgt), of de '(' erin shiften zodat het een functiecall wordt. En bij een shift/reduce conflict kiest ie altijd voor de shift, waardoor de functiecall altijd voor gaat tov een expressie waar een functie uit rolt om aan te roepen.

Ik moet dus op zien te lossen dat ie dat conflict niet meer heeft...

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-09 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
aargh stom |:(

De rhs van de . operator kan alleen maar een identifier zijn, en niets anders.
Het shift/reduce conflict blijf je wel houden voor andere operatoren, maar de functie-call gaat boven al die andere operatoren, dus daar maakt het verder ook niets uit :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Ik vond het al een beetje vreemd dat je daar een identifier had staan (ik was even aan het kijken in bison). Ik ben geen LALR(1) grammatica gewend waar gebruikt wordt gemaakt van precedence operatoren. Als ik een bepaalde precedence wil hebben, dan zal ik dat moeten oplossen mbv productie regels.

Ik heb al eens zitten spelen met SDR grammatica`s, maar helaas is de parser generator daarvoor (voor java) gebonden aan het *nix platform. En ik draai alleen windows.


persoon."get"+"Voornaam"+();

:+ tis wel erg krachtig ;)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-09 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Alarmnummer schreef op 09 augustus 2002 @ 20:37:
Ik vond het al een beetje vreemd dat je daar een identifier expression had staan (ik was even aan het kijken in bison).
expression bedoel je neem ik aan?
Maar zeg dat dan meteen!!! Nou heb ik er 3 uur op zitten broeden voor ik erachter was :Y)
Ik ben geen LALR(1) grammatica gewend waar gebruikt wordt gemaakt van precedence operatoren. Als ik een bepaalde precedence wil hebben, dan zal ik dat moeten oplossen mbv productie regels
dat vind ik dus ook het fijne aan bison/yacc, je hoeft niet van die ingewikkelde constructies te verzinnen :) (okee, zo ingewikkeld zijn ze ook weer niet, maar het kost je wel meer tijd)
Ik heb al eens zitten spelen met SDR grammatica`s, maar helaas is de parser generator daarvoor (voor java) gebonden aan het *nix platform. En ik draai alleen windows.
SDR? Wat is daar de eigenschap van?
persoon."get"+"Voornaam"+();
:+ tis wel erg krachtig ;)
:D
tis maar wat je krachtig noemt... vind het meer een misfeature ;)
net zoals dat je in php (en veel andere scripttalen) een variabele kunt accessen mbv een string-variabele die de naam van de andere variabele bevat. iieuw! :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Ik gebruik zelf SableCC LALR(1) parser generator en daarin missen dit soort dingen. Maar daarintegen genereerd hij wel een volledige AST (inclusied source files waarop je dus onmogelijk iets anders kan doen dan in je grammatica is gedefinieerd, dus erg veilig en superhandig en leesbaar). En dit wordt geserveerd met een snufje visitor inclusief wat gepeperde visitor guide`s, waardoor het supereenvoudig is om een multipass parser te schrijven aangezien je gewoon door een AST heen kan wandelen die perfect op maat is gemaakt voor jouw grammatica) Van alle parser generators voor java is dit afgezien van JJTraveler de meest handige in mijn ogen.

De maker van SableCC geeft in zijn thesis ook duidelijk de verschillen aan tussen een aantal parser generators oa Yacc/Bison.

http://www.sablecc.org (zie sig) :)

ps: SDR moet SDF zijn.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-09 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
tja de syntax trees moet je bij yacc/bison jammer genoeg wel zelf genereren idd... hoewel het wel fijn is dat je code tussen de productieregels kunt proppen (of kan dat met SableCC ook?) En bison ondersteunt ook geen EBNF... hoewel de *, + en ? makkelijk zelf te maken zijn mbv extra productieregels (ik mis vooral de ? voor optionele dingen)

Di's overigens de eerste keer dat ik met bison, of eigenlijk met grammatica's in het algemeen, speel :) (hoewel ik vorig jaar wel compilerbouw heb gehad op school... maar dat was nogal abstract)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Wat bedoel je met code tussen de regels te proppen?

Trouwens sableCC ondersteund ook geen volledige EBNF maar voldoende om er goed mee uit te voeten te kunnen. Het probleem zit hem bij volledige EBNF implementatie dat ze de getters en setters van de genereerde AST niet goed voor elkaar kunnen krijgen en daarnaast heb je misschien wel een leuk syntax, maar een vervelendere AST (en daar zit je 99% van de tijd mee te werken).

Bij ons op school hebben we in theorie wel wat over grammatica`s gehad, en over compilers. Maar nooit genoeg om in praktijk in te zetten. Ik ben eerst bezg geweest met ANTLR, een LL(k) parser generator, maar LL(k) grammatica`s zuigen tov LR(1) grammatica`s . En verder heb je geen handige AST waardoor je kan wandelen dus traversa is een drama.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-09 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Alarmnummer schreef op 09 augustus 2002 @ 21:31:
Wat bedoel je met code tussen de regels te proppen?


nou hier heb je een stukje voorbeeldcode wat gewoon simpele integer arithmetic doet:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
cintexpr    /* expression which evaluates to an integer constant */
    : '~' cintexpr          { $$ = ~$2; }
    | '!' cintexpr          { $$ = !$2; }
    | '+' cintexpr %prec PLUS   { $$ = $2; }
    | '-' cintexpr %prec MIN    { $$ = -$2; }
    | cintexpr '+' cintexpr     { $$ = $1 + $3; }
    | cintexpr '-' cintexpr     { $$ = $1 - $3; }
    | cintexpr '*' cintexpr     { $$ = $1 * $3; }
    | cintexpr '/' cintexpr     { $$ = $1 / $3; }
    | cintexpr '%' cintexpr     { $$ = $1 % $3; }
    | '|' cintexpr '|'      { $$ = ($2 >= 0) ? $2 : -$2; }
    | '(' cintexpr ')'      { $$ = $2; }
    | INT_C             { $$ = $1; }


(INT_C is een terminal, een integer constant)

cintexpr is gedefinieerd als type int. $$ staat voor het resultaat van de non-terminal, en $1 .. $n zijn de componenten van elke productieregel

zonder die code doet het gewoon helemaal niets; bison geeft alleen parse errors als de invoer niet klopt (en dus niet voldoet aan de grammatica). De syntax tree moet je dan ook zelf bouwen.

Het mooie is dat je per regel gewoon code uit kunt voeren. Bovenstaat stukje levert ook altijd een integer constant op op een plaats waar cintexpr gevraagd wordt. Dat is handig want soms is de hele boom totaal niet interessant.
Stel je wilt een array declareren met 3 elementen. De grammatica wordt zoiets:

code:
1
array_decl: type '[' cintexpr ']' identifier;


nu kun je gewoon dit doen:

code:
1
int[4 + (5 - 3) * 56 / 4] blaat;


en cintexpr krijgt gewoon de waarde 32. Het zou natuurlijk onzin zijn om voor de hele expressie 4 + (5 - 3) * 56 / 4 een boom te genereren als je alleen maar geinteresseerd bent in het resultaat


en de boom bouwen doe je zo: (even een stukje koppiepeest uit mijn grammatica)
code:
1
2
3
4
5
if_statement        /* if statement */
    : IF '(' expression ')' statement
        { $$ = new IfStatement ($3, $5); }
    | IF '(' expression ')' statement ELSE statement
        { $$ = new IfStatement ($3, $5, $7); }


(En IfStatement is weer een subklasse van Statement, met een expression als conditie, en 2 statements die al dan niet uitgevoerd moeten worden)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

aaaarrrggghhhhh.... dit is baddddddd ;)

In de parser hoor je productie regels in te plaatsen en niet meteen een AST uit op te bouwen (Ik hoop trouwens dat dat je AST is en niet je IR, want anders ga ik echt hard gillen ;) ). Je krijgt hierdoor een onoverzichtelijke brei met regels en code door elkaar. Is er in bison geen andere manier om je AST op te bouwen?

ps. Als je het echt netjes wilt doen moet je een AST opbouwen waarin de syntax van je text staat. Hierop kan je ideaal mbv het visitor design pattern traversals op uitvoeren en kan je je IR mee vullen. In je IR komen dus de echte objecten te staan waarin je geinteresseerd bent.

Het is misschien wel een omslachtige manier om te werken, maar zo werkt het wel het pretigste.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-09 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
sorry, IR ? :?

maar goed, als je de AST niet in de parser opbouwt, wanneer moet het dan? De parser groepeert alles in boomvorm, dus als je het dan niet doet heb je daarna niets

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

.oisyn schreef op 10 augustus 2002 @ 02:26:
sorry, IR ? :?

maar goed, als je de AST niet in de parser opbouwt, wanneer moet het dan? De parser groepeert alles in boomvorm, dus als je het dan niet doet heb je daarna niets
IR = Intermediate Representation.

Hierin staan dus de echte dingen zoals Variable en PlusOperator objecten in tegenstelling tot de ASTVariable en ASTPlusOperator. En bij het omzetten van je AST naar IR ga je dus semantische controles uitvoeren zoals type controles 10+true (dit is geen c ;) ) en controle of variablen ook gedeclareerd zijn (of misschien wel voor de 2e keer).

Die AST kan je beschouwen als een XML structuur waardoor je kan wandelen. En waarmee je de echte objecten (IR) gaat vullen. Doordat die AST langere tijd blijft bestaan kan je er ook meerdere keren doorheen lopen ipv dat je bv forward declaraties moet doen (multi pass parser).

Als het niet op een andere plek kan dan moet het daar maar. Maar bouw aub wel eerst een AST op zodat je op een andere plek die semantische controles kan uitvoeren ipv je parser ermee te verzieken (ik heb met ANTLR die ervaring opgedaan en dat is iets wat je van je leven niet weer wilt doen).

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-09 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
ah ja okee, ik bouwde dus alleen een AST. Pas daarna ga ik semantische controles uitvoeren en alle objecten opbouwen.

Het wordt trouwens een java-achtige scripttaal met native support voor vector en matrix berekeningen en een ingebouwde statemachine, bedoelt voor gebruik in games :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

.oisyn schreef op 10 augustus 2002 @ 02:43:
ah ja okee, ik bouwde dus alleen een AST. Pas daarna ga ik semantische controles uitvoeren en alle objecten opbouwen.

Het wordt trouwens een java-achtige scripttaal met native support voor vector en matrix berekeningen en een ingebouwde statemachine, bedoelt voor gebruik in games :)
Als je nog met types aan de slag wilt dan raad ik je deze eens aan:
On understanding types, data abstraction, and polymorphism

Ik ben op dit moment bezig met een type systeem voor een functionele programmeertaal gebaseerd op de lamda calculus en ben daar op dit moment een 2e orde type systeem voor aan het schrijven met oa generics en abstracte datatypes. Met dat stuk krijg je een behoorlijk goedzicht hoe het in elkaar zit en op zijn site staan nog genoeg andere stukken om de basis te krijgen voor een 1e implementatie.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

.oisyn schreef op 10 augustus 2002 @ 02:43:
ah ja okee, ik bouwde dus alleen een AST. Pas daarna ga ik semantische controles uitvoeren en alle objecten opbouwen.

Het wordt trouwens een java-achtige scripttaal met native support voor vector en matrix berekeningen en een ingebouwde statemachine, bedoelt voor gebruik in games :)
Wat je trouwens ook kan doen is op basis van jouw script taal gewoon c code genereren. En dat kan je dan compileren met alle snelheids/integratie voordelen van dien.

Dit kan gelukkig vrij eenvoudig omdat je op die IR een andere backend kan plaatsen. Je zou zelfs de backend ook kunnen vervangen voor bv VB zonder dat je in de rest van jouw taal daar ook maar enige hinder van ondervind.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-09 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
ik was wel van plan mijn code-generator te abstraheren zodat ik er evt zo een andere voor in de plaats kan zetten, maar ik was niet van plan het om te zetten naar een andere taal waar vervolgens weer machinetaal van wordt gemaakt.
Als ik er c-code van maak moet de gebruiker weer een c-compiler hebben om dat te kunnen compilen, en bovendien heeft ie dan de kans om unsafe code in het spel te laden (wat niet de bedoeling is). Ik converteer het gewoon naar bytecode wat ik waarschijnlijk JIT ga omzetten naar machinecode. Game logic code is snel genoeg om zelfs geinterpreteerd te worden, dus dat is het probleem niet (ter vergelijking: de game logic van Quake1, wat op een snelle 486 DX goed liep, werd ook gewoon geinterpreteerd :))

Ook is het zo dat als ik er c-code van maak dat ik het moet compilen naar dll's oid... mijn eigen bestandsformaat lijkt me handiger omdat ik het dan beter in het spel kan passen en makkelijker gebruik kan maken van plug-ins en dergelijke

.edit: en dan zitten ze te zeuren over niveau... snap jij dat nou? :P

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

:p

Ik heb al een systeem geschreven dat intepreteerd met een lastige vorm van logica (niet monotoon), waardoor je een zeer complex oplos algoritme eerst kreeg. Maar het nieuwe systeem is voor mijn afstudeerverslag en ik wil eens iets met code generatie gaan doen. Ik wil zelf niet direct naar bytecode compileren omdat je sourcecode een stuk beter kan controleren dan bytecode

Als je trouwens niet zoveel zin hebt om zelf een typesysteem te maken, dan moet je Nice ff ophalen. Het typesysteem dat ze gebruiken is afgeleid van dat van ML (de moeder de geavanceerde type systemen) en is dus geschreven in java.

Verwijderd

whoa, jullie postings lezende bemerk ik hoe ver die handel is weggezakt... :)

/me neemt Aho-Sethi-Ullman maar weer eens ter hand.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-09 21:01

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Alarmnummer schreef op 10 augustus 2002 @ 10:51:
Als je trouwens niet zoveel zin hebt om zelf een typesysteem te maken, dan moet je Nice ff ophalen. Het typesysteem dat ze gebruiken is afgeleid van dat van ML (de moeder de geavanceerde type systemen) en is dus geschreven in java.


ik zie eerlijk gezegd het probleem niet van een eigen typesysteem... Je kwam een paar posts terug ook met dat artikel, maar ik zie totaal de relevantie niet met mijn scripttaal eigenlijk... en het lijkt me ook totaal niet moeilijk een typesysteem als dat voor in mijn scripttaal te implementeren. Maar misschien zie ik nu ook iets compleet over het hoofd :P

Mijn taal is heel erg java-like, met wat enkele aanpassingen. Er zijn in principe 3 primitieven: int, float en string, en er is nog een variant (geleend uit vb :)), die al die 3 typen kan bevatten (inclusief arrays daarvan)

Verder zijn er nog wat syntactische suiker primitieven als statevars, flags en enumerations

En natuurlijk het klassesysteem. Gewoon single-inheritance en interfaces. Ik weet nog niet of ik function parameter overloading ga toepassen, waarschijnlijk niet, dus problemen met coercion zal ik ook niet echt krijgen...

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Dat klinkt als een redelijk gecompliceerd type systeem, dus verkijk je er aub niet op. Je zult overal van moeten kunnen bepalen of het een subtype ed is. En verder loop je daarnaast nog een keer met int float problemen te kampen en dan hebben we het nog niet eens over die akelige null. (Kan je heel elegant oplossen dmv een variant constructie en als je dan ook nog een speciale taal constructie toevoegt dan kan je bijna geen nullpointer problemen meer krijgen, je dwing mensen dus om het per case af te handelen).

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
(sorry voor de grote schop, vakantie ;) )
.oisyn schreef op 09 augustus 2002 @ 20:55:SDF? Wat is daar de eigenschap van?
SDF is een Syntax Defintion Formalism. Het unieke van SDF is dat het de volledige klasse van context-vrije grammatica toestaat. Dit heeft voor bepaalde toepassingen grote voordelen, maar uiteraard ook nadelen.

Doordat de volledige klasse van context-vrije grammatica's is toegestaan onstaan er echte wat interessante voordelen: de enige subklasse van context-vrije grammatica's die gesloten is onder de operaties union, difference en intersection is namelijk de klasse van de context-vrije grammatica's zelf. Hierdoor bezit SDF unieke modulaire eigenschappen en is het een ideaal syntax definitie formalisme om talen samen te voegen tot 1 taal. Als je twee LR grammatica's samenvoegt is er bijvoorbeeld geen garantie dat de nieuwe grammatica nog steeds in de subklasse LR grammatica's van de context-vrije grammatica's valt. De subklasse LR grammatica is dus niet gesloten onder de union operatie. Hierdoor kan je twee LR grammatica's nooit zomaar samenvoegen, laat staan dat je een grammatica zomaar zou kunnen opbouwen uit losse modulen.

Bij scannerless generalized LR parsing (wat SDF support) zijn ambiguiteiten toegestaan: het is mogelijk dat er meerdere productie-regels toegepast kunnen worden. Uiteraard zijn zulke ambiguiteiten niet bepaald wenselijk en daarom kunnen ze gewoon opgelost worden. Dit gebeurt echter niet door de grammatica te verkrachten en de taal-ontwikkelaar te beperken tot een bepaalde subklasse van context-vrije grammatica's, maar door disambiguatie-filters te gebruiken.

Alle deze goodies kosten natuurlijk aardig wat, zoals ook al opgemerkte staat in het boek van Aho &zo . De complexiteit van het parsen van de volledige klasse van context-vrije grammatica's is aardig hoog en het parsen gaat hierdoor een flink stukje trager. Het is daarom vooral geschikt voor software-renovatie, talen in het ontwikkeling en specialistische tools. Je gaat geen SGLR gebruiken in een compiler die zwaar en door veel mensen gebruikt gaat worden.

Als je dit boeiend materiaal vindt kan je bijvoorbeeld eens deze twee stukken lezen. Het staat hier allemaal wat beter uitgelegd dan dat ik dat kan:

A Quick Introduction to SDF
Current Parsing Techniques in Software Renovation Considered Harmful

Eventueel kan je ook de Java grammatica in SDF bekijken waaraan ik werk. Als je deze grammatica vergelijke met de grammatica in de language specification wordt al snel duidelijk wat de voordelen van SDF zijn. Ik ben er absoluut niet blij mee dat talen gespecificeerd worden met een bepaald parsing-algoritme in gedachten. Deze verbouwing van de grammatica hoort niet thuis in een specificatie van een taal.

http://www.mbravenboer.org/java_front.xhtml

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment

Pagina: 1