parser: add qualified module names
[nit.git] / src / parser / nit.sablecc3xx
index 5628f0b..323e465 100644 (file)
@@ -57,12 +57,12 @@ blank = (' ' | tab)+;
 eol = eol_helper;
 comment = '#' any* eol_helper;
 
-kwpackage = 'package';
+kwmodule = 'package'|'module';
 kwimport = 'import';
 kwclass = 'class';
 kwabstract = 'abstract';
 kwinterface = 'interface';
-kwuniversal = 'universal';
+kwenum = 'universal'|'enum';
 kwspecial = 'special';
 kwend = 'end';
 kwmeth = 'fun';
@@ -129,8 +129,10 @@ eq = '==';
 ne = '!=';
 lt = '<';
 le = '<=';
+ll = '<<';
 gt = '>';
 ge = '>=';
+gg = '>>';
 starship = '<=>';
 bang='!';
 
@@ -159,14 +161,14 @@ Productions
 
 /* MODULES *******************************************************************/
 module
-       = packagedecl? [imports]:import* [classdefs]:classdef* implicit_top_class? implicit_main_class? {-> New module(packagedecl, [imports.import],[classdefs.classdef,implicit_top_class.classdef,implicit_main_class.classdef])};
+       = moduledecl? [imports]:import* [classdefs]:classdef* implicit_top_class? implicit_main_class? {-> New module(moduledecl, [imports.import],[classdefs.classdef,implicit_top_class.classdef,implicit_main_class.classdef])};
 
-packagedecl
-       = [doc]:no kwpackage no id [n2]:n1 {-> New packagedecl(doc.doc, kwpackage, id)};
+moduledecl
+       = [doc]:no kwmodule no module_name [n2]:n1 {-> New moduledecl(doc.doc, kwmodule, module_name)};
 
 import
-       = {std} [doc]:no visibility kwimport no id [n2]:n1              {-> New import.std(visibility, kwimport, id)}
-       | {no} [doc]:no visibility kwimport no kwend [n2]:n1    {-> New import.no(visibility, kwimport, kwend)}
+       = {std} [doc]:no visibility kwimport no module_name [n2]:n1 {-> New import.std(visibility, kwimport, module_name)}
+       | {no} [doc]:no visibility kwimport no kwend [n2]:n1 {-> New import.no(visibility, kwimport, kwend)}
        ;
 
 implicit_top_class {-> classdef}
@@ -190,7 +192,7 @@ classkind
        = {concrete} kwclass
        | {abstract} kwabstract kwclass
        | {interface} kwinterface
-       | {universal} kwuniversal
+       | {enum} kwenum
        ;
 
 formaldefs {-> formaldef*}
@@ -214,8 +216,10 @@ propdef~toplevel {-> propdef}
 !toplevel| {deferred} [doc]:no redef visibility kwmeth methid signature kwis kwabstract {-> New propdef.deferred_meth(doc.doc, redef.kwredef, visibility, kwmeth, methid, signature.signature)}
 !toplevel| {intern} [doc]:no redef visibility kwmeth methid signature kwis kwintern {-> New propdef.intern_meth(doc.doc, redef.kwredef, visibility, kwmeth, methid, signature.signature)}
        | {extern} [doc]:no redef visibility kwmeth methid signature kwis kwextern string? {-> New propdef.extern_meth(doc.doc, redef.kwredef, visibility, kwmeth, methid, signature.signature, string)}
-!toplevel| {var} [doc]:no readable? writable? redef visibility kwvar attrid typing? {-> New propdef.attr(doc.doc, readable.able, writable.able, redef.kwredef, visibility, kwvar, attrid, typing.type, Null)}
-!toplevel| {var2} [doc]:no readable? writable? redef visibility kwvar attrid typing? assign [n2]:no expr {-> New propdef.attr(doc.doc, readable.able, writable.able, redef.kwredef, visibility, kwvar, attrid, typing.type, expr)}
+!toplevel| {var} [doc]:no readable? writable? redef visibility kwvar attrid typing? {-> New propdef.attr(doc.doc, readable.able, writable.able, redef.kwredef, visibility, kwvar, attrid, Null, typing.type, Null)}
+!toplevel| {var2} [doc]:no readable? writable? redef visibility kwvar attrid typing? assign [n2]:no expr {-> New propdef.attr(doc.doc, readable.able, writable.able, redef.kwredef, visibility, kwvar, attrid, Null, typing.type, expr)}
+!toplevel| {var3} [doc]:no redef visibility kwvar id typing? writable2? {-> New propdef.attr(doc.doc, Null, writable2.able, redef.kwredef, visibility, kwvar, Null, id, typing.type, Null)}
+!toplevel| {var4} [doc]:no redef visibility kwvar id typing? writable2? assign [n2]:no expr {-> New propdef.attr(doc.doc, Null, writable2.able, redef.kwredef, visibility, kwvar, Null, id, typing.type, expr)}
 !toplevel| {init} [doc]:no redef visibility kwinit methid? signature kwdo stmtso kwend? {-> New propdef.concrete_init(doc.doc, redef.kwredef, visibility, kwinit, methid, signature, stmtso.expr)}
 !toplevel| {type} [doc]:no redef visibility kwtype classid typing {-> New propdef.type(doc.doc, redef.kwredef, visibility, kwtype, classid, typing.type)}
        ;
@@ -223,7 +227,10 @@ readable {-> able}
        = redef kwreadable {-> New able.read(redef.kwredef, kwreadable)}
        ;
 writable {-> able}
-       = redef kwwritable {-> New able.write(redef.kwredef, kwwritable)}
+       = redef kwwritable {-> New able.write(redef.kwredef, Null, kwwritable)}
+       ;
+writable2 {-> able}
+       = redef visibility kwwritable {-> New able.write(redef.kwredef, visibility, kwwritable)}
        ;
 
 visibility
@@ -246,6 +253,8 @@ methid {-> methid}
        | {ge} ge {-> New methid.ge(ge)}
        | {lt} lt {-> New methid.lt(lt)}
        | {gt} gt {-> New methid.gt(gt)}
+       | {ll} ll {-> New methid.ll(ll)}
+       | {gg} gg {-> New methid.gg(gg)}
        | {bra} obra cbra {-> New methid.bra(obra, cbra)}
        | {starship} starship {-> New methid.starship(starship)}
        | {assign} id assign {-> New methid.assign(id, assign)}
@@ -400,8 +409,8 @@ while~withelse {-> expr}
        ;
 
 for~withelse {-> expr}
-       = kwfor no id [n2]:no kwin [n3]:no expr [n4]:no kwdo stmtso_withend label {-> New expr.for(kwfor, id, expr, kwdo, stmtso_withend.expr, label)}
-       | {nolabel} kwfor no id [n2]:no kwin [n3]:no expr [n4]:no kwdo stmtso~withelse {-> New expr.for(kwfor, id, expr, kwdo, stmtso~withelse.expr, Null)}
+       = kwfor no [ids]:idlist [n2]:no kwin [n3]:no expr [n4]:no kwdo stmtso_withend label {-> New expr.for(kwfor, [ids.id], expr, kwdo, stmtso_withend.expr, label)}
+       | {nolabel} kwfor no [ids]:idlist [n2]:no kwin [n3]:no expr [n4]:no kwdo stmtso~withelse {-> New expr.for(kwfor, [ids.id], expr, kwdo, stmtso~withelse.expr, Null)}
        ;
 
 assert~withelse {-> expr}
@@ -442,8 +451,10 @@ expr_eq~nopar~nobra {-> expr}
        | {ne} expr_add~nopar~nobra ne no [expr2]:expr_add~nopar~nobra {-> New expr.ne(expr_add~nopar~nobra.expr, expr2.expr)}
        | {lt} expr_add~nopar~nobra lt no [expr2]:expr_add~nopar~nobra {-> New expr.lt(expr_add~nopar~nobra.expr, expr2.expr)}
        | {le} expr_add~nopar~nobra le no [expr2]:expr_add~nopar~nobra {-> New expr.le(expr_add~nopar~nobra.expr, expr2.expr)}
+       | {ll} expr_eq~nopar~nobra ll no [expr2]:expr_add~nopar~nobra {-> New expr.ll(expr_eq~nopar~nobra.expr, expr2.expr)}
        | {gt} expr_add~nopar~nobra gt no [expr2]:expr_add~nopar~nobra {-> New expr.gt(expr_add~nopar~nobra.expr, expr2.expr)}
        | {ge} expr_add~nopar~nobra ge no [expr2]:expr_add~nopar~nobra {-> New expr.ge(expr_add~nopar~nobra.expr, expr2.expr)}
+       | {gg} expr_eq~nopar~nobra gg no [expr2]:expr_add~nopar~nobra {-> New expr.gg(expr_eq~nopar~nobra.expr, expr2.expr)}
        | {starship} expr_add~nopar~nobra starship no [expr2]:expr_add~nopar~nobra {-> New expr.starship(expr_add~nopar~nobra.expr, expr2.expr)}
        | {isa} expr_add~nopar~nobra kwisa no type~nobra {-> New expr.isa(expr_add~nopar~nobra.expr, type~nobra.type)}
        ;
@@ -480,7 +491,7 @@ expr_atom~nopar~nobra {-> expr}
        | {init} recv~nopar~nobra kwinit args {-> New expr.init(recv~nopar~nobra.expr, kwinit, [args.expr])}
 !nobra | {bra} expr_atom~nopar braargs {-> New expr.bra(expr_atom~nopar.expr, [braargs.expr], [])}
        | {new} kwnew no type~nobra dot [n2]:no id args {-> New expr.new(kwnew, type~nobra.type, id, [args.expr])}
-// FIXME: Why are these 3 !nopar mandatory?
+// !nopar to unambiguise 'foo[5].bar' between '(foo[5]).bar' and 'foo([5].bar),
 !nobra!nopar   | {range} obra no expr [n2]:no dotdot [n3]:no [expr2]:expr_nobra [n4]:no cbra {-> New expr.crange(expr, expr2.expr)}
 !nobra!nopar   | {orange} obra no expr [n2]:no dotdot [n3]:no [expr2]:expr_nobra [n4]:no [cbra]:obra  {-> New expr.orange(expr, expr2.expr)}
 !nobra!nopar   | {array} braargs {-> New expr.array([braargs.expr])}
@@ -542,6 +553,11 @@ idlist_nopar {-> id*}
        | {more} idlist_nopar no comma [n2]:no id {-> [idlist_nopar.id, id]}
        ;
 
+module_name {-> module_name}
+       = {mod} modquad* id {-> New module_name(Null, [modquad.id], id)}
+       | {root} quad no modquad* id {-> New module_name(quad, [modquad.id], id)}
+       ;
+
 qualified 
        = {cla} modquad* classquad {-> New qualified([modquad.id], classquad.classid)}
        | {mod} modquad+ {-> New qualified([modquad.id], Null)}
@@ -570,12 +586,12 @@ n2
 Abstract Syntax Tree
 /*****************************************************************************/
 
-module = packagedecl? [imports]:import* [classdefs]:classdef*;
+module = moduledecl? [imports]:import* [classdefs]:classdef*;
 
-packagedecl
-       = doc? kwpackage id;
+moduledecl
+       = doc? kwmodule [name]:module_name;
 
-import = {std} visibility kwimport id
+import = {std} visibility kwimport [name]:module_name
        | {no} visibility kwimport kwend
        ;
 
@@ -594,13 +610,13 @@ classkind
        = {concrete} kwclass
        | {abstract} kwabstract kwclass
        | {interface} kwinterface
-       | {universal} kwuniversal
+       | {enum} kwenum
        ;
 formaldef = [id]:classid type?;
 superclass = kwspecial? kwsuper? type;
 
 
-propdef = {attr} doc? [readable]:able? [writable]:able? kwredef? visibility kwvar [id]:attrid type? expr?
+propdef = {attr} doc? [readable]:able? [writable]:able? kwredef? visibility kwvar [id]:attrid? [id2]:id? type? expr?
        | {meth} doc? kwredef? visibility methid signature 
        | {deferred_meth} doc? kwredef? visibility kwmeth methid signature 
        | {intern_meth} doc? kwredef? visibility kwmeth methid signature 
@@ -612,14 +628,14 @@ propdef = {attr} doc? [readable]:able? [writable]:able? kwredef? visibility kwva
        ;
 
 able   = {read} kwredef? kwreadable
-       | {write} kwredef? kwwritable
+       | {write} kwredef? visibility? kwwritable
        ;
 
-methid = {id} id | {plus} plus | {minus} minus | {star} star | {slash} slash | {percent} percent | {eq} eq | {ne} ne | {le} le | {ge} ge | {lt} lt | {gt} gt | {bra} obra cbra | {starship} starship | {assign} id assign | {braassign} obra cbra assign;
+methid = {id} id | {plus} plus | {minus} minus | {star} star | {slash} slash | {percent} percent | {eq} eq | {ne} ne | {le} le | {ge} ge | {lt} lt | {gt} gt |  {ll} ll | {gg} gg | {bra} obra cbra | {starship} starship | {assign} id assign | {braassign} obra cbra assign;
 
 signature = [params]:param* type? [closure_decls]:closure_decl*;
 
-param  = id type? dotdotdot? 
+param  = id type? dotdotdot?
        ;
 
 closure_decl = kwbreak? bang id signature expr?
@@ -640,7 +656,7 @@ expr        = {block} expr*
        | {ifexpr} kwif expr kwthen [then]:expr kwelse [else]:expr
        | {while} kwwhile expr kwdo [block]:expr? label?
        | {loop} kwloop [block]:expr? label?
-       | {for} kwfor id expr kwdo [block]:expr? label?
+       | {for} kwfor [ids]:id* expr kwdo [block]:expr? label?
        | {assert} kwassert id? expr [else]:expr?
        | {once} kwonce expr 
        | {send} expr 
@@ -654,8 +670,10 @@ expr       = {block} expr*
        | {ne} expr [expr2]:expr 
        | {lt} expr [expr2]:expr 
        | {le} expr [expr2]:expr 
+       | {ll} expr [expr2]:expr
        | {gt} expr [expr2]:expr 
        | {ge} expr [expr2]:expr 
+       | {gg} expr [expr2]:expr
        | {isa} expr type 
        | {plus} expr [expr2]:expr 
        | {minus} expr [expr2]:expr 
@@ -715,6 +733,8 @@ closure_id
        | {break} kwbreak
        ;
 
+module_name = quad? [path]:id* id;
+
 qualified = id* classid? ;
 
 doc = comment+;