Skip to content

Commit

Permalink
- Fixed some more issues in the ANTLR3 parser (97 of 1036 testcases f…
Browse files Browse the repository at this point in the history
…ailing now)

  - Still needs to be able to work as string parser (CORBA communication, etc)
  - Needs to be checked for performance issues (loadFile() is faster, but instantiateModel() is slower when working on the generated data structures)
  - Needs to have two (or three) different lexers (for Modelica, MetaModelica, maybe flat Modelica modes)
    - Currently, there are some special macros for MetaModelica stuff, but these are ugly
- Moved around in the testsuite: created a parser library strictly for testing lexing/parsing/unparsing
  - One of the new testcases does not work with the ANTLR2 parser, because it can't switch between MetaModelica and Modelica mode


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@5999 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Sep 2, 2010
1 parent aafe19f commit 10dae7a
Show file tree
Hide file tree
Showing 6 changed files with 348 additions and 607 deletions.
7 changes: 6 additions & 1 deletion Compiler/runtime/rtopts.c
Expand Up @@ -630,13 +630,18 @@ RML_BEGIN_LABEL(RTOpts__versionRequest)
}
RML_END_LABEL

int accept_meta_modelica_grammar()
{
return acceptedGrammar == GRAMMAR_METAMODELICA;
}

/*
* adrpo 2007-06-11
* flag for accepting only Modelica grammar or also MetaModelica grammar
*/
RML_BEGIN_LABEL(RTOpts__acceptMetaModelicaGrammar)
{
if (acceptedGrammar == GRAMMAR_METAMODELICA)
if (accept_meta_modelica_grammar())
rmlA0 = RML_PRIM_MKBOOL(RML_TRUE);
else
rmlA0 = RML_PRIM_MKBOOL(RML_FALSE);
Expand Down
37 changes: 37 additions & 0 deletions Compiler/runtime/rtopts.h
@@ -0,0 +1,37 @@
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-2010, Linköpings University,
* Department of Computer and Information Science,
* SE-58183 Linköping, Sweden.
*
* All rights reserved.
*
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THIS OSMC PUBLIC
* LICENSE (OSMC-PL). ANY USE, REPRODUCTION OR DISTRIBUTION OF
* THIS PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THE OSMC
* PUBLIC LICENSE.
*
* The OpenModelica software and the Open Source Modelica
* Consortium (OSMC) Public License (OSMC-PL) are obtained
* from Linköpings University, either from the above address,
* from the URL: http://www.ida.liu.se/projects/OpenModelica
* and in the OpenModelica distribution.
*
* This program is distributed WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS
* OF OSMC-PL.
*
* See the full OSMC Public License conditions for more details.
*
*/

#ifndef __RTOPTS_H
#define __RTOPTS_H

int check_debug_flag(char const* strdata);
int accept_meta_modelica_grammar(void);

#endif
6 changes: 5 additions & 1 deletion Parser/Makefile
Expand Up @@ -2,7 +2,7 @@ RMLHOME=/usr
COMPILERHOME=../Compiler/
LIBRML=-lrml -lm
ANTLRCMD=java -cp ./antlr-3.2/lib/antlr-3.2.jar org.antlr.Tool -report
CFLAGS=-g -O3
CFLAGS=-O3 -g
LDFLAGS=-L$(RMLHOME)/lib/plain/ $(LIBRML) -L. -lantlr3
CPPFLAGS=-I$(COMPILERHOME) -I$(RMLHOME)/include/plain -I. -Iantlr-3.2/runtime/C -Iantlr-3.2/runtime/C/include
CC=gcc
Expand All @@ -16,6 +16,10 @@ libantlr3.a: antlr-3.2/runtime/C/src/* antlr-3.2/runtime/C/include/*
ranlib libantlr3.a
rm -f antlr3*.o

ModelicaLexer.o: ModelicaParserCommon.h
ModelicaParser.o: ModelicaParserCommon.h
parse.o: ModelicaLexer.h ModelicaParser.h ModelicaParserCommon.h

libomparse.a: parse.o ModelicaLexer.o ModelicaParser.o
ar -ru $@ parse.o ModelicaLexer.o ModelicaParser.o
ranlib $@
Expand Down
158 changes: 115 additions & 43 deletions Parser/Modelica.g
Expand Up @@ -115,7 +115,7 @@ tokens {
// Operators
// ---------
DOT = '.' ;
DOT = '.' ;
LPAR = '(' ;
RPAR = ')' ;
LBRACK = '[' ;
Expand Down Expand Up @@ -189,14 +189,22 @@ EMPTY;
OPERATOR;
}
@lexer::includes {
#include "ModelicaParserCommon.h"
#define METAMODELICA_REAL_OP() {if (metamodelica_enabled() && (LA(1)=='.' && (LA(2) == ' ' || LA(2)=='\t' || LA(2)=='\n'))) LEXER->matchc(LEXER,'.');}
#define METAMODELICA_REAL_STRING_OP() {if (metamodelica_enabled() && (LA(1)=='&' || (LA(1)=='.' && (LA(2) == ' ' || LA(2)=='\t' || LA(2)=='\n')))) LEXER->matchAny(LEXER);}
}
@includes {
#include <stdio.h>
#include "rml.h"
#include "Absyn.h"
/* Eat anything so we can test code gen */
void* mk_box_eat_all(int ix, ...);
#define modelicaParserAssert(cond,msg,func) if (cond) { CONSTRUCTEX(); EXCEPTION->type = ANTLR3_RECOGNITION_EXCEPTION; EXCEPTION->message = (void *) msg; EXCEPTION->decisionNum = -1; EXCEPTION->state = -1; goto rule ## func ## Ex; }
#include "Interactive.h"
#include "ModelicaParserCommon.h"
#define ModelicaParserException -1
#define ModelicaLexerException -2
#define modelicaParserAssert(cond,msg,func) if (cond) { CONSTRUCTEX(); EXCEPTION->type = ModelicaParserException; EXCEPTION->message = (void *) msg; goto rule ## func ## Ex; }
#define false 0
#define true 1
Expand All @@ -207,6 +215,8 @@ OPERATOR;
#define make_inner_outer(i,o) (i && o ? Absyn__INNEROUTER : i ? Absyn__INNER : o ? Absyn__OUTER : Absyn__UNSPECIFIED)
#define mk_bcon(x) (x ? RML_TRUE : RML_FALSE)
#if 0
/* Enable if you want to test this as a walker instead of a parser */
void* mk_box_eat_all(int ix, ...);
#define mk_scon(x) x
#define mk_rcon(x) mk_box_eat_all(0,x)
#define mk_box0(x1) mk_box_eat_all(x1)
Expand All @@ -229,17 +239,15 @@ OPERATOR;
#define RML_STRUCTHDR(x,y) 0
#endif
#define token_to_scon(tok) mk_scon(tok->getText(tok)->chars)
#define metamodelica_enabled(void) 0
#define code_expressions_enabled(void) 0
#define NYI(void) fprintf(stderr, "NYI \%s \%s:\%d\n", __FUNCTION__, __FILE__, __LINE__); exit(1);
#define INFO(start) Absyn__INFO(ModelicaParser_filename, isReadOnly, mk_icon(start->line), mk_icon(start->charPosition+1), mk_icon(LT(1)->line), mk_icon(LT(1)->charPosition+1), Absyn__TIMESTAMP(mk_rcon(0),mk_rcon(0)))
typedef unsigned char bool;
extern void *ModelicaParser_filename;
#define INFO(start) Absyn__INFO(ModelicaParser_filename_RML, isReadOnly, mk_icon(start->line), mk_icon(start->charPosition+1), mk_icon(LT(1)->line), mk_icon(LT(1)->charPosition+1), Absyn__TIMESTAMP(mk_rcon(0),mk_rcon(0)))
}
@members
{
void* ModelicaParser_filename = 0;
void* ModelicaParser_filename_RML = 0;
const char* ModelicaParser_filename_C = 0;
int ModelicaParser_flags = 0;
void* isReadOnly = RML_FALSE;
void* mk_box_eat_all(int ix, ...) {return NULL;}
double getCurrentTime(void) {
Expand All @@ -256,17 +264,17 @@ OPERATOR;
* LEXER RULES
*------------------------------------------------------------------*/
STAR : '*'('.')? ;
MINUS : '-'('.')? ;
PLUS : '+'('.'|'&')? ;
LESS : '<'('.')? ;
LESSEQ : '<='('.')? ;
LESSGT : '!='('.')?|'<>'('.')? ;
GREATER : '>'('.')? ;
GREATEREQ : '>='('.')? ;
EQEQ : '=='('.'|'&')? ;
POWER : '^'('.')? ;
SLASH : '/'('.')? ;
STAR : '*' {METAMODELICA_REAL_OP()};
MINUS : '-' {METAMODELICA_REAL_OP()};
PLUS : '+' {METAMODELICA_REAL_STRING_OP()};
LESS : '<' {METAMODELICA_REAL_OP()};
LESSEQ : '<=' {METAMODELICA_REAL_OP()};
LESSGT : '<>' {METAMODELICA_REAL_OP()}; /* '!=' */
GREATER : '>' {METAMODELICA_REAL_OP()};
GREATEREQ : '>=' {METAMODELICA_REAL_OP()};
EQEQ : '==' {METAMODELICA_REAL_STRING_OP()};
POWER : '^' {METAMODELICA_REAL_OP()};
SLASH : '/' {METAMODELICA_REAL_OP()};
WS : ( ' ' | '\t' | NL )+ { $channel=HIDDEN; }
;
Expand Down Expand Up @@ -344,6 +352,7 @@ SESCAPE : '\\' ('\\' | '"' | '\'' | '?' | 'a' | 'b' | 'f' | 'n' | 'r' | 't' | 'v
stored_definition returns [void* ast] :
(within=within_clause SEMICOLON)?
cl=class_definition_list?
EOF
{
ast = Absyn__PROGRAM(or_nil(cl), within ? within : Absyn__TOP, Absyn__TIMESTAMP(mk_rcon(0.0), mk_rcon(getCurrentTime())));
}
Expand Down Expand Up @@ -502,7 +511,7 @@ external_clause returns [void* ast] :
( ann1 = annotation )? SEMICOLON
( ann2 = external_annotation )?
{
ast = Absyn__EXTERNALDECL(mk_some_or_none(funcname), mk_some_or_none(lang), mk_some_or_none(retexp), or_nil(expl), mk_some_or_none(ann1));
ast = Absyn__EXTERNALDECL(funcname ? mk_some(token_to_scon(funcname)) : mk_none(), mk_some_or_none(lang), mk_some_or_none(retexp), or_nil(expl), mk_some_or_none(ann1));
ast = mk_cons(Absyn__EXTERNAL(ast, mk_some_or_none(ann2)), mk_nil());
}
;
Expand Down Expand Up @@ -742,8 +751,16 @@ element_modification [void *each, void *final] returns [void* ast] :

element_redeclaration returns [void* ast] :
REDECLARE (e=EACH)? (f=FINAL)?
( (class_definition[f != NULL] | component_clause1) | element_replaceable[e != NULL,f != NULL,true] )
{ NYI(); }
( (cdef=class_definition[f != NULL] | cc=component_clause1) | er=element_replaceable[e != NULL,f != NULL,true] )
{
if (er) {
ast = er;
} else {
if (!cc)
cc = Absyn__CLASSDEF(RML_FALSE,cdef.ast);
ast = Absyn__REDECLARATION(mk_bcon(f), make_redeclare_keywords(false,true), e ? Absyn__EACH : Absyn__NON_5fEACH, cc, mk_none());
}
}
;

element_replaceable [bool each, bool final, bool redeclare] returns [void* ast] :
Expand All @@ -756,11 +773,14 @@ element_replaceable [bool each, bool final, bool redeclare] returns [void* ast]
;

component_clause1 returns [void* ast] :
type_prefix type_specifier component_declaration1 { NYI(); }
attr=base_prefix ts=type_specifier comp_decl=component_declaration1
{
ast = Absyn__COMPONENTS(attr, ts, mk_cons(comp_decl, mk_nil()));
}
;

component_declaration1 returns [void* ast] :
declaration comment { NYI(); }
decl=declaration cmt=comment { ast = Absyn__COMPONENTITEM(decl, mk_none(), mk_some_or_none(cmt)); }
;


Expand Down Expand Up @@ -815,7 +835,7 @@ equation returns [void* ast] :
;

algorithm returns [void* ast] :
( a=assign_clause_a
( ({metamodelica_enabled()}? a=mm_assign_clause_a | {!metamodelica_enabled()}? a=assign_clause_a)
| a=conditional_equation_a
| a=for_clause_a
| a=while_clause
Expand All @@ -833,26 +853,28 @@ algorithm returns [void* ast] :
;

assign_clause_a returns [void* ast] :
( {!metamodelica_enabled()}?
( cr=component_reference
( (ASSIGN|EQUALS {NYI();}) e=expression {ast = Absyn__ALG_5fASSIGN(Absyn__CREF(cr),e);}
| fc=function_call {ast = Absyn__ALG_5fNORETCALL(cr,fc);}
)
| LPAR es=expression_list RPAR ASSIGN
cr=component_reference fc=function_call {ast = Absyn__ALG_5fASSIGN(Absyn__TUPLE(es),Absyn__CALL(cr,fc));}
( cr=component_reference
( (ASSIGN|EQUALS {NYI();}) e=expression {ast = Absyn__ALG_5fASSIGN(Absyn__CREF(cr),e);}
| fc=function_call {$ast = Absyn__ALG_5fNORETCALL(cr,fc);}
)
| LPAR es=expression_list RPAR
( ASSIGN cr=component_reference fc=function_call {$ast = Absyn__ALG_5fASSIGN(Absyn__TUPLE(es),Absyn__CALL(cr,fc));}
)
| {metamodelica_enabled()}? /* MetaModelica allows pattern matching on arbitrary expressions in algorithm sections... */
e1=simple_expression
( (ASSIGN|EQUALS) e2=expression {ast = Absyn__ALG_5fASSIGN(e1,e2);}
| {RML_GETHDR(e1) == RML_STRUCTHDR(2, Absyn__CALL_3dBOX2)}? /* It has to be a CALL */
{
struct rml_struct *p = (struct rml_struct*)RML_UNTAGPTR(e1);
ast = Absyn__ALG_5fNORETCALL(p->data[0],p->data[1]);
}
)
)
;

mm_assign_clause_a returns [void* ast] :
/* MetaModelica allows pattern matching on arbitrary expressions in algorithm sections... */
e1=simple_expression
( (ASSIGN|EQUALS) e2=expression {$ast = Absyn__ALG_5fASSIGN(e1,e2);}
| {RML_GETHDR(e1) == RML_STRUCTHDR(2, Absyn__CALL_3dBOX2)}? /* It has to be a CALL... or match/continue? deal with those later */
{
struct rml_struct *p = (struct rml_struct*)RML_UNTAGPTR(e1);
$ast = Absyn__ALG_5fNORETCALL(p->data[0],p->data[1]);
}
)
;

equality_or_noretcall_equation returns [void* ast] :
e1=simple_expression
( EQUALS e2=expression {ast = Absyn__EQ_5fEQUALS(e1,e2);}
Expand Down Expand Up @@ -1260,6 +1282,7 @@ annotation returns [void* ast] :


/* Code quotation mechanism */

code_expression returns [void* ast] :
CODE LPAR ((expression RPAR)=> e=expression | m=modification | el=element (SEMICOLON)?
| eq=code_equation_clause | ieq=code_initial_equation_clause
Expand All @@ -1285,4 +1308,53 @@ code_initial_algorithm_clause :
INITIAL T_ALGORITHM
( algorithm SEMICOLON | annotation SEMICOLON )*
;

/* End Code quotation mechanism */


top_algorithm returns [void* ast, bool isExp] :
( aa=top_assign_clause_a
| a=conditional_equation_a
| a=for_clause_a
| a=while_clause
)
cmt=comment
{
if (a || !aa.isExp) {
$ast = Absyn__ALGORITHMITEM(a ? a : aa.ast, mk_some_or_none(cmt), INFO($start));
$isExp = 0;
} else {
$ast = aa.ast;
$isExp = 1;
}
}
;

top_assign_clause_a returns [void* ast, bool isExp] :
(e1=simple_expression|e1=code_expression) (ASSIGN e2=expression)?
{
if (e2) {
$ast = Absyn__ALG_5fASSIGN(e1,e2);
$isExp = 0;
} else {
$ast = e1;
$isExp = 1;
}
}
;

interactive_stmt returns [void* ast] :
// A list of expressions or algorithms separated by semicolons and optionally ending with a semicolon
ss=interactive_stmt_list EOF {ast = Interactive__ISTMTS(or_nil(ss), RML_TRUE);}
;

interactive_stmt_list returns [void* ast] :
a=top_algorithm SEMICOLON ss=interactive_stmt_list?
{
if (!a.isExp)
ast = mk_cons(Interactive__IALG(a.ast), or_nil(ss));
else
ast = mk_cons(Interactive__IEXP(a.ast), or_nil(ss));
}
;

48 changes: 48 additions & 0 deletions Parser/ModelicaParserCommon.h
@@ -0,0 +1,48 @@
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-CurrentYear, Linkoping University,
* Department of Computer and Information Science,
* SE-58183 Linkoping, Sweden.
*
* All rights reserved.
*
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3
* AND THIS OSMC PUBLIC LICENSE (OSMC-PL).
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S
* ACCEPTANCE OF THE OSMC PUBLIC LICENSE.
*
* The OpenModelica software and the Open Source Modelica
* Consortium (OSMC) Public License (OSMC-PL) are obtained
* from Linkoping University, either from the above address,
* from the URLs: http://www.ida.liu.se/projects/OpenModelica or
* http://www.openmodelica.org, and in the OpenModelica distribution.
* GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
*
* This program is distributed WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS
* OF OSMC-PL.
*
* See the full OSMC Public License conditions for more details.
*
*/

#ifndef MODELICA_PARSER_COMMON_H
#define MODELICA_PARSER_COMMON_H

typedef unsigned char bool;
extern int ModelicaParser_flags;
extern void *ModelicaParser_filename_RML;
extern const char *ModelicaParser_filename_C;

#define PARSE_MODELICA 0
#define PARSE_FLAT 1<<0
#define PARSE_META_MODELICA 1<<1
#define PARSE_EXPRESSION 1<<2
#define PARSE_CODE_EXPRESSION 1<<3
#define metamodelica_enabled(void) (ModelicaParser_flags&PARSE_META_MODELICA)
#define code_expressions_enabled(void) (ModelicaParser_flags&PARSE_CODE_EXPRESSION)

#endif

0 comments on commit 10dae7a

Please sign in to comment.