rperz86
rperz86

Reputation: 135

Illegal Argument: ParseTree error on small language

I'm stuck on this problem for a while now, hope you can help. I've got the following (shortened) language grammar:

lexical Id  = [a-zA-Z][a-zA-Z]* !>> [a-zA-Z] \ MyKeywords;
lexical Natural = [1-9][0-9]* !>> [0-9];
lexical StringConst = "\"" ![\"]*  "\"";

keyword MyKeywords = "value" | "Male" | "Female";

start syntax Program = program:  Model* models;
syntax Model = Declaration;
syntax Declaration = decl: "value" Id name ':' Type t "=" Expression v ;
syntax Type = gender: "Gender";
syntax Expression = Terminal;
syntax Terminal = id: Id name
                | constructor: Type t '(' {Expression ','}* ')'
                | Gender;
syntax Gender = male: "Male"
              | female: "Female";

alias ASLId = str;
data TYPE = gender();
public data PROGRAM = program(list[MODEL] models); 
data MODEL = decl(ASLId name, TYPE t, EXPR v);
data EXPR = constructor(TYPE t, list[EXPR] args) 
          | id(ASLId name)                
          | male()
          | female(); 

Now, I'm trying to parse:

value mannetje : Gender = Male  

This parses fine, but fails on implode, unless I remove the id: Id name and it's constructor from the grammar. I expected that the /MyKeywords would prevent this, but unfortunately it doesn't. Can you help me fix this, or point me in the right direction to how to debug? I'm having some trouble with debugging the Concrete and Abstract syntax.

Thanks!

Upvotes: 1

Views: 157

Answers (2)

Tijs van der Storm
Tijs van der Storm

Reputation: 111

Two things:

  • The names of the ADTs should correspond to the nonterminal names (you have difference cases and EXPR is not Expression). That is the only way implode can now how to do its work. Put the data decls in their own module and implode as follows: implode(#AST::Program, pt) where pt is the parse tree.

  • The grammar was ambiguous: the \ MyKeywords only applied to the tail of the identifier syntax. Use the fix: ([a-zA-Z][a-zA-Z]* !>> [a-zA-Z]) \ MyKeywords;.

Here's what worked for me (grammar unchanged except for the fix):

module AST

alias ASLId = str;
data Type = gender();
public data Program = program(list[Model] models); 
data Model = decl(ASLId name, Type t, Expression v);
data Expression = constructor(Type t, list[Expression] args) 
      | id(ASLId name)                
      | male()
      | female(); 

Upvotes: 2

Jouke Stoel
Jouke Stoel

Reputation: 65

It does not seem to be parsing at all (I get a ParseError if I try your example).

One of the problems is probably that you don't define Layout. This causes the ParseError with you given example. One of the easiest fixes is to extend the standard Layout in lang::std::Layout. This layout defines all the default white spaces (and comment) characters. For more information on nonterminals see here.

I took the liberty in simplifying your example a bit further so that parsing and imploding works. I removed some unused nonterminals to keep the parse tree more concise. You probably want more that Declarations in your Program but I leave that up to you.

extend lang::std::Layout;

lexical Id  = ([a-z] !<< [a-z][a-zA-Z]* !>> [a-zA-Z]) \ MyKeywords;

keyword MyKeywords = "value" | "Male" | "Female" | "Gender";

start syntax Program = program:  Declaration* decls;

syntax Declaration = decl: "value" Id name ':' Type t "=" Expression v ;

syntax Type = gender: "Gender";

syntax Expression
    = id: Id name
    | constructor: Type t '(' {Expression ','}* ')'
    | Gender
    ;

syntax Gender 
    = male: "Male"
    | female: "Female"
    ;

data PROGRAM = program(list[DECL] exprs); 
data DECL = decl(str name, TYPE t, EXPR v);
data EXPR = constructor(TYPE t, list[EXPR] args) 
          | id(str name)                
          | male()
          | female()
          ; 

data TYPE = gender();

Upvotes: 2

Related Questions