OMCCp: A MetaModelica Based Parser Generator Applied to ...

233
Institutionen f¨ or Datavetenskap Department of Computer and Information Science Master’s thesis OMCCp: A MetaModelica Based Parser Generator Applied to Modelica by Edgar Alonso Lopez-Rojas LIU-IDA/LITH-EX-A–11/019–SE 2011-05-31 Link¨ opings universitet SE-581 83 Link¨ oping, Sweden Link¨ opings universitet 581 83 Link¨ oping

Transcript of OMCCp: A MetaModelica Based Parser Generator Applied to ...

Page 1: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Institutionen for DatavetenskapDepartment of Computer and Information Science

Master’s thesis

OMCCp: A MetaModelica BasedParser Generator Applied to Modelica

by

Edgar Alonso Lopez-Rojas

LIU-IDA/LITH-EX-A–11/019–SE

2011-05-31'

&

$

%Linkopings universitet

SE-581 83 Linkoping, Sweden

Linkopings universitet

581 83 Linkoping

Page 2: OMCCp: A MetaModelica Based Parser Generator Applied to ...
Page 3: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Institutionen for DatavetenskapDepartment of Computer and Information Science

Master’s thesis

OMCCp: A MetaModelica BasedParser Generator Applied to Modelica

by

Edgar Alonso Lopez-Rojas

LIU-IDA/LITH-EX-A–11/019–SE

2011-05-31

Supervisors: Martin Sjolund and Mohsen Torabzadeh-TariDept. of Computer and Information Science

Examiner: Prof. Peter FritzsonDept. of Computer and Information Science

Page 4: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Upphovsratt

Detta dokument halls tillgangligt pa Internet a eller dess framtidaersattare a under en langre tid fran publiceringsdatum underforutsattning att inga extra-ordinara omstandigheter uppstar.Tillgang till dokumentet innebar tillstand for var och en att lasa,ladda ner, skriva ut enstaka kopior for enskilt bruk och att anvandadet oforandrat for ickekommersiell forskning och for undervisning.overforing av upphovsratten vid en senare tidpunkt kan inte upphavadetta tillstand. All annan anvandning av dokumentet kraver up-phovsmannens medgivande. For att garantera aktheten, sakerhetenoch tillgangligheten finns det losningar av teknisk och administrativart.Upphovsmannens ideella ratt innefattar ratt att bli namnd som up-phovsman i den omfattning som god sed kraver vid anvandning avdokumentet pa ovan beskrivna satt samt skydd mot att dokumentetandras eller presenteras i sadan form eller i sadant sammanhangsom ar krankande for upphovsmannens litterara eller konstnarligaanseende eller egenart.For ytterligare information om Linkoping University ElectronicPress se forlagets hemsida http://www.ep.liu.se/

Copyright

The publishers will keep this document online on the Internet - orits possible replacement - for a considerable time from the date ofpublication barring exceptional circumstances.The online availability of the document implies a permanent per-mission for anyone to read, to download, to print out single copiesfor your own use and to use it unchanged for any non-commercialresearch and educational purpose. Subsequent transfers of copyrightcannot revoke this permission. All other uses of the document areconditional on the consent of the copyright owner. The publisher hastaken technical and administrative measures to assure authenticity,security and accessibility.According to intellectual property law the author has the right to bementioned when his/her work is accessed as described above and tobe protected against infringement.For additional information about the Linkoping University Elec-tronic Press and its procedures for publication and for assuranceof document integrity, please refer to its WWW home page:http://www.ep.liu.se/

c©Edgar Alonso Lopez-Rojas

Page 5: OMCCp: A MetaModelica Based Parser Generator Applied to ...

To Isabella, my new project in life

Page 6: OMCCp: A MetaModelica Based Parser Generator Applied to ...
Page 7: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Abstract

The OpenModelica Compiler-Compiler parser generator (OMCCp) is anLALR(1) parser generator implemented in the MetaModelica language withparsing tables generated by the tools Flex and GNU Bison. The code gener-ated for the parser is in MetaModelica 2.0 language which is the OpenMod-elica compiler implementation language and is an extension of the Modelica3.2 language. OMCCp uses as input an LALR(1) grammar that specifies theModelica language. The generated Parser can be used inside the OpenMod-elica Compiler (OMC) as a replacement for the current parser generated bythe tool ANTLR from an LL(k) Modelica grammar. This report explainsthe design and implementation of this novel Lexer and Parser Generatorcalled OMCCp.Modelica and its extension MetaModelica are both languages used in theOpenModelica environment. Modelica is an Object-Oriented Equation-Based language for Modeling and Simulation.

v

Page 8: OMCCp: A MetaModelica Based Parser Generator Applied to ...

vi

Page 9: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Acknowledgements

It is an honor for me to be able to culminate this work with the guidanceof remarkable computer scientists. This thesis would not have been possibleunless the clear vision of my examiner, professor Peter Fritzson. As thedirector of the Open Source Modelica Consortium (OSMC) he presented thisgreat opportunity to me. Together with him, I have to thank my supervisorsMartin Sjolund and Mohsen Torabzadeh-Tari. Martin has made availablehis support and guidance in a number of ways that I cannot count andMohsen has always been keeping track of my progress and helping me withthe difficulties I found. I am pleased to be part, learn and contribute to thisgreat open source project called OpenModelica.

Nevertheless, To IDA (Department of Computer and Information Sci-ence) for offering its locations and resources for my daily work.

I cannot forget to thank my family. My parents Jesus and Soledad forsupporting me since the beginning in this project to become a Master inComputer Science. My fiancee Helena, who has all the time been encour-aging me to give my best in every step of this journey. I am delighted toinclude my future daughter Isabella here; who is been my biggest motivationto complete this work before the day she step for the first time in this world.

Last, but not less important my financial sponsors from Colombia: Fun-dacion Colfuturo1 and EAFIT University2. They believed in my talent andprovided the financial resources to achieve this goal.

1http://www.colfuturo.org/2http://www.eafit.edu.co/

vii

Page 10: OMCCp: A MetaModelica Based Parser Generator Applied to ...

viii

Page 11: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Contents

1 Introduction 11.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Project Goal . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.3 Methodology . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.4 Intended Readers . . . . . . . . . . . . . . . . . . . . . . . . . 31.5 Thesis Outline . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Theoretical Background 52.1 Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.1.1 Fundamentals . . . . . . . . . . . . . . . . . . . . . . . 62.1.2 Lexical Analysis . . . . . . . . . . . . . . . . . . . . . 82.1.3 Syntax Analysis . . . . . . . . . . . . . . . . . . . . . 102.1.4 Parser LALR(1) . . . . . . . . . . . . . . . . . . . . . 13

2.2 Error Handling in Syntax Analysis . . . . . . . . . . . . . . . 152.2.1 Error Recovery . . . . . . . . . . . . . . . . . . . . . . 162.2.2 Error Messages . . . . . . . . . . . . . . . . . . . . . . 17

2.3 The OpenModelica Project . . . . . . . . . . . . . . . . . . . 172.3.1 The Modelica Language . . . . . . . . . . . . . . . . . 182.3.2 MetaModelica extension . . . . . . . . . . . . . . . . . 182.3.3 Abstract Syntax Tree - AST . . . . . . . . . . . . . . 21

3 Existing Technologies 233.1 OpenModelica Compiler (OMC) . . . . . . . . . . . . . . . . 23

3.1.1 Architecture and Components . . . . . . . . . . . . . . 233.1.2 ANTLR . . . . . . . . . . . . . . . . . . . . . . . . . . 243.1.3 Current state . . . . . . . . . . . . . . . . . . . . . . . 26

3.2 Flex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273.2.1 Input file lexer.l . . . . . . . . . . . . . . . . . . . . . 273.2.2 Output file lexer.c . . . . . . . . . . . . . . . . . . . . 27

3.3 GNU Bison . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283.3.1 Input file parser.y . . . . . . . . . . . . . . . . . . . . 293.3.2 Output file parser.c . . . . . . . . . . . . . . . . . . . 29

ix

Page 12: OMCCp: A MetaModelica Based Parser Generator Applied to ...

x CONTENTS

4 Implementation 334.1 Proposed Solution . . . . . . . . . . . . . . . . . . . . . . . . 334.2 OMCCp Design . . . . . . . . . . . . . . . . . . . . . . . . . . 34

4.2.1 Lexical Analyser . . . . . . . . . . . . . . . . . . . . . 354.2.2 Syntax Analyser . . . . . . . . . . . . . . . . . . . . . 39

4.3 OpenModelica Compiler-Compiler Parser (OMCCp) . . . . . 444.3.1 Lexer Generator . . . . . . . . . . . . . . . . . . . . . 444.3.2 Parser Generator . . . . . . . . . . . . . . . . . . . . . 46

4.4 Error handling . . . . . . . . . . . . . . . . . . . . . . . . . . 494.4.1 Error recovery . . . . . . . . . . . . . . . . . . . . . . 494.4.2 Error messages . . . . . . . . . . . . . . . . . . . . . . 50

4.5 Integration OMC . . . . . . . . . . . . . . . . . . . . . . . . . 54

5 Discussion 575.1 Analysis of Results . . . . . . . . . . . . . . . . . . . . . . . . 57

5.1.1 Lexer and Parser . . . . . . . . . . . . . . . . . . . . . 575.1.2 OMCCp Construction . . . . . . . . . . . . . . . . . . 585.1.3 Implementation of a subset of Modelica and Meta-

Modelica grammar . . . . . . . . . . . . . . . . . . . . 615.2 OpenModelica Compiler . . . . . . . . . . . . . . . . . . . . . 645.3 Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

6 Related Work 666.1 OpenModelica Development . . . . . . . . . . . . . . . . . . . 666.2 Compiler-Compiler Construction . . . . . . . . . . . . . . . . 67

7 Conclusions 697.1 Accomplishments . . . . . . . . . . . . . . . . . . . . . . . . . 697.2 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

Bibliography 73

Appendices 80

A OMC Compiler Commands 80A.1 Parameters - MetaModelica Parser Generator . . . . . . . . . 80

A.1.1 Generate compilerName . . . . . . . . . . . . . . . . . 80A.1.2 Run compilerName, fileName . . . . . . . . . . . . . . 80

A.2 OMC Commands . . . . . . . . . . . . . . . . . . . . . . . . . 80

B Lexer Generator 83B.1 Lexer.mo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83B.2 LexerGenerator.mo . . . . . . . . . . . . . . . . . . . . . . . . 92B.3 LexerCode.tmo . . . . . . . . . . . . . . . . . . . . . . . . . . 100B.4 Types.mo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

Page 13: OMCCp: A MetaModelica Based Parser Generator Applied to ...

CONTENTS xi

C Parser Generator 107C.1 Parser.mo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107C.2 ParserGenerator.mo . . . . . . . . . . . . . . . . . . . . . . . 126C.3 ParseCode.tmo . . . . . . . . . . . . . . . . . . . . . . . . . . 143

D Sample Input 146D.1 lexer10.l . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146D.2 parser10.y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147

E Sample Output 152E.1 ParseTable10.mo . . . . . . . . . . . . . . . . . . . . . . . . . 152E.2 ParseCode10.mo . . . . . . . . . . . . . . . . . . . . . . . . . 157E.3 Token10.mo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168E.4 LexTable10.mo . . . . . . . . . . . . . . . . . . . . . . . . . . 168E.5 LexerCode10.mo . . . . . . . . . . . . . . . . . . . . . . . . . 171

F Modelica Grammar 176F.1 lexerModelica.l . . . . . . . . . . . . . . . . . . . . . . . . . . 176F.2 parserModelica.y . . . . . . . . . . . . . . . . . . . . . . . . . 180

G Additional Files 205G.1 SCRIPT.mos . . . . . . . . . . . . . . . . . . . . . . . . . . . 205G.2 Main.mo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206

Glossary 209

Acronyms 211

Page 14: OMCCp: A MetaModelica Based Parser Generator Applied to ...

xii CONTENTS

Page 15: OMCCp: A MetaModelica Based Parser Generator Applied to ...

List of Figures

2.1 Compiler Phases . . . . . . . . . . . . . . . . . . . . . . . . . 62.2 Compiler Front-End . . . . . . . . . . . . . . . . . . . . . . . 82.3 Parser components . . . . . . . . . . . . . . . . . . . . . . . . 122.4 OpenModelica Environment [Fritzson et al., 2009] . . . . . . 18

3.1 OMC simplified overall structure [Fritzson et al., 2009] . . . . 243.2 OMC Language Grammars . . . . . . . . . . . . . . . . . . . 24

4.1 OMCCp (OpenModelica Compiler - Compiler) Lexer and ParserGenerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

4.2 OMCCp Lexer and Parser Generator Architecture Design . . 364.3 OMC-Lexer design . . . . . . . . . . . . . . . . . . . . . . . . 374.4 OMC-Parser design . . . . . . . . . . . . . . . . . . . . . . . . 394.5 OMC-Parser LALR(1) . . . . . . . . . . . . . . . . . . . . . . 40

5.1 OMCCp - Time Parsing . . . . . . . . . . . . . . . . . . . . . 63

xiii

Page 16: OMCCp: A MetaModelica Based Parser Generator Applied to ...

xiv LIST OF FIGURES

Page 17: OMCCp: A MetaModelica Based Parser Generator Applied to ...

List of Tables

2.1 LR(1) parsing table [Aho et al., 2006] . . . . . . . . . . . . . 142.2 LR(1) parsing table rearranged [Aho et al., 2006] . . . . . . . 142.3 LALR(1) parsing table [Aho et al., 2006] . . . . . . . . . . . . 15

5.1 OMCCp Files Implementation . . . . . . . . . . . . . . . . . . 605.2 Test Suite - Compiler . . . . . . . . . . . . . . . . . . . . . . 635.3 OMCCp - Time Parsing . . . . . . . . . . . . . . . . . . . . . 63

xv

Page 18: OMCCp: A MetaModelica Based Parser Generator Applied to ...

xvi LIST OF TABLES

Page 19: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Listings

2.1 MetaModelica uniontype . . . . . . . . . . . . . . . . . . . . . 192.2 MetaModelica matchcontinue . . . . . . . . . . . . . . . . . . 202.3 MetaModelica list . . . . . . . . . . . . . . . . . . . . . . . . 203.1 ANTLR grammar file structure . . . . . . . . . . . . . . . . . 253.2 Flex file structure . . . . . . . . . . . . . . . . . . . . . . . . . 273.3 Bison file structure . . . . . . . . . . . . . . . . . . . . . . . . 294.1 Lexer.mo function scan . . . . . . . . . . . . . . . . . . . . . . 374.2 Parser.mo function parse . . . . . . . . . . . . . . . . . . . . . 414.3 MultiTypedStack AstStack . . . . . . . . . . . . . . . . . . . 434.4 ParseCode.mo case reduce action . . . . . . . . . . . . . . . . 434.5 ParseCode.mo function getAST . . . . . . . . . . . . . . . . . 444.6 Modifications in the Bison Epilogue . . . . . . . . . . . . . . 464.7 Modifications in the Rules section in Bison . . . . . . . . . . 474.8 List of semantic values of tokens . . . . . . . . . . . . . . . . 484.9 Constants for error handling . . . . . . . . . . . . . . . . . . . 504.10 Custom error messages in OMCCp . . . . . . . . . . . . . . . 534.11 Error messages in OMCCp . . . . . . . . . . . . . . . . . . . 534.12 program.mo with errors . . . . . . . . . . . . . . . . . . . . . 544.13 Parser.mo original function . . . . . . . . . . . . . . . . . . . 544.14 Parser.mo modified function . . . . . . . . . . . . . . . . . . . 55A.1 Compile Flex and Bison . . . . . . . . . . . . . . . . . . . . . 81A.2 OMCC.mos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81A.3 OMCCP Command . . . . . . . . . . . . . . . . . . . . . . . 81A.4 SCRIPT.mos debug mode . . . . . . . . . . . . . . . . . . . . 82A.5 OMCCP debug mode . . . . . . . . . . . . . . . . . . . . . . 82B.1 Lexer.mo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83B.2 LexerGenerator.mo . . . . . . . . . . . . . . . . . . . . . . . . 92B.3 LexerCode.tmo . . . . . . . . . . . . . . . . . . . . . . . . . . 100B.4 Types.mo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102C.1 Parser.mo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107C.2 ParserGenerator.mo . . . . . . . . . . . . . . . . . . . . . . . 126C.3 ParseCode.tmo . . . . . . . . . . . . . . . . . . . . . . . . . . 143D.1 lexer10.l . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146D.2 parser10.y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147

xvii

Page 20: OMCCp: A MetaModelica Based Parser Generator Applied to ...

xviii LISTINGS

E.1 ParseTable10.mo . . . . . . . . . . . . . . . . . . . . . . . . . 152E.2 ParseCode10.mo . . . . . . . . . . . . . . . . . . . . . . . . . 157E.3 Token10.mo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168E.4 LexTable10.mo . . . . . . . . . . . . . . . . . . . . . . . . . . 169E.5 LexerCode10.mo . . . . . . . . . . . . . . . . . . . . . . . . . 171F.1 lexerModelica.l . . . . . . . . . . . . . . . . . . . . . . . . . . 176F.2 parserModelica.y . . . . . . . . . . . . . . . . . . . . . . . . . 180G.1 SCRIPT.mos . . . . . . . . . . . . . . . . . . . . . . . . . . . 205G.2 Main.mo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206

Page 21: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Chapter 1

Introduction

1.1 Background

The OpenModelica project develops a modeling and simulation environment

based on the Modelica language [Fritzson, 2004]. The effort is supported by

the Open Source Modelica Consortium (OSMC). It uses the OpenModel-

ica Compiler (OMC) [Fritzson et al., 2009] to generate either C, C++ or

C code that runs simulations which are written in the Modelica language.

OpenModelica currently makes use of the tool called Another Tool for Lan-

guage Recognition (ANTLR) to generate the Parser for the OpenModelica

Compiler (OMC). The work presented in this master’s thesis offers an al-

ternative for the ANTLR parser. We present a novel Compiler-Compiler

implemented completely on MetaModelica. MetaModelica is an extension

of the Modelica language intended for modeling the semantics of languages.

One large example is the modeling of the whole Modelica language together

with its MetaModelica extensions in the OpenModelica bootstrapped com-

piler version [Sjolund et al., 2011].

The ANTLR parser generator [Parr and Quong, 1995], which is already

used in the OpenModelica project since several years, has well known dis-

advantages including memory overhead, bad error handling, lack of type

checking, and not generating MetaModelica code for building the Abstract

Syntax Tree (AST). Since the AST nodes are initially generated in C (for

later conversion into MetaModelica) without strong type checking, small

errors in the semantic actions in the grammar are not detected at genera-

1

Page 22: OMCCp: A MetaModelica Based Parser Generator Applied to ...

2 CHAPTER 1. INTRODUCTION

tion time, and can give rise to hard-to-find bugs in the generated C code.

When the semantic actions can be specified in MetaModelica and the AST

builder generated in MetaModelica, this source of errors can be completely

eliminated. Currently ANTLR generated parsers connect with OMC by an

external C interface. It is also built as an integrated Lexer and Parser that

hide behind a considerable amount of libraries. These libraries handle as

a black-box the complexity of the syntax analysis process in the compiler.

ANTLR is only suitable for parsing LL grammars.

1.2 Project Goal

The goal of this master’s thesis is to write a parser generator using Meta-

Modelica language that can replace the current parser ANTLR and generates

MetaModelica code instead of C-code.

The results expected from this thesis are:

• A Lexer and a Parser for Modelica grammar including its MetaMod-

elica extension that outputs the Abstract Syntax Tree (AST) for the

language processed.

• Lexer and Parser generator written in the MetaModelica language.

• Improvements in the error handling messages compared with ANTLR;

specifically the messages concerning error correction hints of mal-

formed syntax.

1.3 Methodology

The methodology used for the construction of the OpenModelica Compiler-

Compiler parser generator (OMCCp) is based on a literature study of com-

piler construction techniques. There are various projects that offer lexer and

parser generators but there are none for the Modelica language. A literature

review is the base for the initiation of this project on compiler construction.

Different literature from the OSMC is available. This contributes for a

better understanding on the OpenModelica project. Besides the literature

reviewed, we include the experience of the supervisor Martin Sjorlund. He

built the first bootstrapping compiler for the Modelica Language [Sjolund

et al., 2011]. Various papers and books from the examiner are available.

Page 23: OMCCp: A MetaModelica Based Parser Generator Applied to ...

1.4. INTENDED READERS 3

The examiner has a clear vision of the next steps in the development of the

compiler due to his involvement in the project since it started several years

ago.

There are exercises available for learning the MetaModelica, including

online courses. The exercises are important for familiarisation with the

MetaModelica language. A guide of MetaModelica is also provided to ad-

dress the most common built in functions and limitations of the language.

After the literature review, existing technologies that can support the

project are addressed. A review of the techniques they use and the ben-

efits is performed. This will lead the architectural decisions towards the

implementation of the parser and lexer generator.

Finally the implementation of a subset of the Modelica grammar for the

existing parser generator is addressed. This will finalise the project and

prove the validity of the proposed solution.

1.4 Intended Readers

The reader of this document is someone who wants to understand more

about compiler construction and more specifically the syntax analyser phase

of the OpenModelica Compiler. This document has important information

for the OpenModelica developer who wants to work on the OMC compiler

design and construction.

1.5 Thesis Outline

This thesis gives an overview of the OpenModelica project and the architec-

ture of the OpenModelica compiler. In the Chapter 2, Theoretical Back-

ground, it familiarise the reader with the topic of Compiler Construction.

More specifically the Lexer Analysis and Syntactic Analysis and different

basic concepts about grammars.

This thesis covers the topic of existing technologies in chapter 3 as a

basic understanding for the Implementation.

Finally the Chapters 5 Discussion and 6 Related Work explains different

parts of the project analysing the results of the implementation. The con-

clusions review the achievement of the goals and analyse the implemented

solution. Further work provides the reader who intends to continue this

Page 24: OMCCp: A MetaModelica Based Parser Generator Applied to ...

4 CHAPTER 1. INTRODUCTION

work more information about desired extensions and improvements over

this project.

The appendices cover the source code of the entire project including the

sample generated files from the exercise 10 of the MetaModelica exercises

available in [Fritzson and Pop, 2011a,b]. A large subset of Modelica 3.2

grammar [Modelica-Association, 2010] is also included. It was used to prove

the usability of the parser generator.

Page 25: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Chapter 2

Theoretical Background

“The world as we know it depends on programming languages”

Aho et al. [2006]

We required a strong knowledge of compilers construction theory for

implementing the solution for this thesis. For a better understanding of this

project; the reader must be familiar with some of the fundamental terms

and basic algorithms used for the construction of the lexical analyser and

the parser during this project.

This chapter covers the main topics of compiler construction that are

used on the implementation of the solution presented in Chapter 4. The

next part of this chapter addresses an important topic for this project; which

is the improvement on error handling during the compiler parsing phase.

The last part presents an overview of the current OpenModelica project

including the Modelica and MetaModelica languages and the OMC.

2.1 Compilers

Aho et al. [2006] is a mandatory book for anyone who intends to understand

the concepts of Compilers. Most of the compiler’s theory covered on this

part is based on this book. Other sources such as Kakde [2002] and Terry

[2000] have been reviewed and is addressed in the different subsections. This

section intends to give the reader an introduction of the compiler terms and

techniques used during the design and development of this project.

5

Page 26: OMCCp: A MetaModelica Based Parser Generator Applied to ...

6 CHAPTER 2. THEORETICAL BACKGROUND

2.1.1 Fundamentals

Programming languages rely strongly for their evolution and massive use

on compilers. These languages exist due to the limitations for developers

in building complex systems in machine-language; which only identify se-

quences of binary instructions. However, in a more general view, a Compiler

is a software tool that serves as a translator from one language into another.

Figure 2.1: Compiler Phases

If we see a compiler as a process we can identify the source language as

the input and the target language as the output of this process. For example

in languages such as C, the input language is the C code and the output

language is machine code for a specific architecture and operative system.

Page 27: OMCCp: A MetaModelica Based Parser Generator Applied to ...

2.1. COMPILERS 7

There are several types of compilers used today, and the classification

depends on different purposes of the compilers. We distinguish between

native-compilers, cross-compilers, interpreters and source-to-source compil-

ers translators.

Native-compilers are used for the generation of machine-specific code

(binary code). The cross-compilers generate machine-specific code too; but

they generate the code for a different machine as the one they are running.

The interpreters for languages are similar to the Java virtual machine

(JVM)1. They receive as an input two parameters: the source program

and the input for the program. The interpreter simulates the result of the

compiled source program executed directly in machine-language code. It

outputs the expected result of the source program over the input used as a

parameter.

We are addressing the source-to-source compilers in this report; which

are commonly used for translating one high level language such as Modelica

into another high level language such as C. This technique is common due

to the difficulty of generating low level language code such as Assembler or

directly binary code.

The complexity of a compiler is showed in the figure 2.1, inside a com-

piler there are two main parts that can be recognised, the Analysis (Front-

End) and the Synthesis (Back-End). The Analysis phase is handled by

the Front-End of the compiler. The Front-End is divided into three steps:

Lexical Analysis, Syntax Analysis and Semantic Analysis. These steps as

presented in figure 2.2

The Lexical Analysis task is performed by a component called Lexer.

The main function of the Lexer is to get as an input the source code and

recognised different sequences of characters into a unit called token.

The Front-End is the part of the compiler that we focus on this im-

plementation. During the analysis phase, the source code is processed by

the Lexical Analyser, Syntax Analyser and Semantic Analyser to output an

intermediate representation of the input code called Abstract Syntax Tree

(AST).

1http://www.java.com/

Page 28: OMCCp: A MetaModelica Based Parser Generator Applied to ...

8 CHAPTER 2. THEORETICAL BACKGROUND

input

program

tokens abstract

syntax treethree-address

code

Symbol

Table

Lexer ParserIntermediate

code generator

Compiler Front-End

Figure 2.2: Compiler Front-End

2.1.2 Lexical Analysis

The Lexical Analysis, also called scanning, receives the source code as a

character stream. It identifies the special tokens specified by a language

making it more simple for the next phase of the compiler. The programming

language’s tokens are often specified by the use of Regular Expressions.

A Lexer is a program that runs a Finite Automata which recognises a

valid language based on a regular language. As mentioned above, the regular

languages are described by the use of regular expressions.

The Lexical Analysis is the first part of the compiler. It simplifies the

complexity of recognising a complete grammar, by giving a simple trans-

formation of the source code into a list of tokens. In the next step of the

compiler the syntax analysis uses only the tokens to accept or reject the

source code provided.

For better understanding on how the Lexical Analysis works; we intro-

duce the basic concepts of Finite Automata and Regular Languages in the

next section. We present later a description of what a Lexer specifically

does.

Finite Automata and Regular Languages

Sipser [2005] presents the use of a Finite Automata, also known as Fi-

nite State Machines, to recognize the regular languages. He defines a Fi-

nite Automata as a collection of states (Q), an alphabet (Σ), a transition

function(δ : QxΣ→ Q), a start state (q0) and a set of accept states.

Page 29: OMCCp: A MetaModelica Based Parser Generator Applied to ...

2.1. COMPILERS 9

To describe briefly how a Finite Automata works, the use of state di-

agrams are broadly used. There are two types of Finite Automata, the

first one is Deterministic Finite Automata (DFA) and the other is Non-

Deterministic Finite Automata (NFA).

The Lexer

For the construction of the Lexer it is preferred to use the DFA. However,

a NFA can also be converted into a DFA. A lexer can also simulate the

non-deterministic behaviour of a NFA. The main reason for using a DFA is

that we want to have a transition function δ that allows the Lexer to decide

only one path over a specific char input in the character stream from the

source code.

All the regular expressions of the set of tokens are summarised during the

construction of a Lexer. It often happens that one sequence of characters

can be recognised as two or more different tokens. Therefore, the lexer

must have extra rules that prioritise longer strings over shorter ones. Other

instructions can also be added to order the rules in an accepting sequence

to avoid ambiguity.

The Lexical Analysis phase filters some tokens that are used only by the

programmer such as comments, different kind of spacing and indentation on

the code. This task simplifies the complexity of the code by converting all

the characters in a list of tokens. If the Parser has to deal with this task the

amount of terminal tokens will increased, making the Rules more complex

and decreasing the overall performance of the compiler.

The compiler gains performance when the Lexical Analysis is kept sep-

arated from the Syntax Analysis. This performance can be achieved by ap-

plying specialised techniques in the handling of the character stream, such

as buffering for reading certain amount of characters at the time.

A structure called Symbol Table is used to store all the identifiers with

their names or values, this structure avoids duplication and efficiency of the

code through all the phases of the compiler as represented in the Figure 2.2.

A token is usually represented by a tuple, consisting in an identifier of the

token and a reference to the Symbol Table, e.g. TOKEN < IDENT, x >

where IDENT is the identifier of the token and x is the value found by the

Lexer of the identifier.

Page 30: OMCCp: A MetaModelica Based Parser Generator Applied to ...

10 CHAPTER 2. THEORETICAL BACKGROUND

Flex a Lexer Generator

There are some programs that automate the labour of constructing the

transition rules to identify the tokens for a Lexer. Flex is one example of

a Lexer Generator. It is based on the Lexer generator Lex. It uses as an

input a file with the definition of the rules for the recognition of the tokens.

These rules are defined using regular expressions.

Flex also allows the developer to specify the return token that matches

each pattern. Some tokens such as white spaces and line feeds are ignored

as explained above.

In the next chapter we cover the existing technologies used for this report

and we explain in a technical detail Flex.

2.1.3 Syntax Analysis

The Syntax Analysis phase is performed by a program called Parser. The

Parser requires a more powerful language than regular expression to specify

the programming language constructions. The rules are commonly expressed

using Context Free Grammars (CFG). The CFG can be recognised by the

use of a PushDown Automata.

PushDown Automata and Context Free Languages

Sipser [2005] defines a Context Free Grammar (CFG) as a 4-tuple (V,Σ, R, S),

where V is the set of variables, Σ is a set of terminals, R is a set of Rules

and S is the Start Variable.

A Push-Down Automata (PDA) starts by reading an input set of tokens.

The PDA uses the tokens and a stack to store and decide the next state and

action of the PDA, this action can be to reduce from the stack or to store

any state or token into the stack. By doing this it keeps running until it

finds an accept state and then ends. Several situations can happen including

an infinite loop of the machine. This explains why the grammar should be

constructed in such a way that it avoids these problems.

Similar to the DFA, there are PDA that are deterministic, and those are

the ones we consider for building the Parser.

Page 31: OMCCp: A MetaModelica Based Parser Generator Applied to ...

2.1. COMPILERS 11

The Parser

The Parser is in charge of determining if the source code that has been

tokenised by the Lexer is constructed according to the rules of the grammar.

By doing this, it executes a PDA that outputs “accept”if the input belongs to

a valid construction of the grammar, otherwise it outputs an error message

identifying the token that does not fit the construction rules.

The work done by the Lexer in the first phase of the compiler allows the

Parser to ignore tokens such as white spaces and line feed and consider all

the tokens as terminals of the grammar that describes the language. This

simplifies the rules of the Parser making it more efficient and fast in the

process of syntax analysing.

The Parser validates the rules of the grammar from list of tokens re-

ceived from the Lexer. However at the same time, a Parser can executes

an additional task, which is the construction of a structure called Abstract

Syntax Tree (AST). The AST resembles a tree and it is the representation

of all the source code in a set of three instructions. This is the input for the

compiler Back-End. The Back-End uses this AST for the optimisation and

generation of machine-specific code.

A Parser is composed by a predictive table, a stack of states, a list of

tokens as an input and a parsing algorithm that runs over the list of tokens.

Figure 2.3 shows these components and their interactions.

A Parser uses the predictive tables, also called parsing tables, to deter-

mine the next action and the new state of the machine. The next state is

queried from the parsing tables depending on the lookahead token and the

current state of the stack.

Parsers are commonly classified by the algorithm used for performing the

parsing operation. There are three known types: Top Down Parser, Bottom

Up Parser and Universal Parser. However for programming languages only

the first two are utilised due to the inefficiency of the Universal Parser.

A Top-Down Parser builds the parse tree from the top to the bottom.

Bottom Up Parser works in the opposite direction as the Top Down Parser.

Top Down Parsers only work for grammars called Left to right, Left most

derivation parser (LL). A LL(k) Parser is a top descendant parser with k

lookahead tokens. LL(k) Parsers utilise a predictive table to decide the next

state.

Bottom-Up Parsers are based on grammars Left to right, Right most

Page 32: OMCCp: A MetaModelica Based Parser Generator Applied to ...

12 CHAPTER 2. THEORETICAL BACKGROUND

Tokens

ParsingTables

PARSER

AST

State Stack

lookahead

Figure 2.3: Parser components

derivation parser (LR). Knuth [1965] introduced first the concept of LR

parsing. The most common parsers are LR(k), Simple LR parser (SLR) and

Look Ahead LR parser (LALR). The Parser LALR(1) uses a simplification

of the parsing tables used by the LR(1) parser.

In general a Bottom Up Parser builds the AST by performing two types

of task: Shift and Reduce.

Shift allocates the variable or terminal symbol found while the machine

goes through the list of tokens. It utilise a table called Action Table; which

contains all terminals and rules for calculating the next state. The table

called GOTO Table is used for calculating the next state. When the result

is calculated it pushes these values back into the state stack.

Reduce pops a certain number of values from the stack to apply later

a push with a new value also using the GOTO Table. While reducing a

LALR parser can build up the AST and push the new value into another

stack called Semantic Stack which also follows the rules of shift and reducing

performed by the algorithm.

Blasband [2001] made an effort in parsing grammars that do not perfectly

fit into the classification of LL and LALR grammars.

On this report we briefly look at Top Down Parsers. We are more inter-

ested in the LALR(1) Bottom Up Parser; which is the type of parser used

in this implementation. The parser LALR(1) is explained in more detail in

the next section.

Page 33: OMCCp: A MetaModelica Based Parser Generator Applied to ...

2.1. COMPILERS 13

2.1.4 Parser LALR(1)

The LALR(k) parsers were first introduced by DeRemer [1969]. They are

the most commonly parsers used in programming languages due to the speed

and size of the parsing tables and the advantages over its predecessors the

LR(0) and SLR(0) parsers.

Kakde [2002] and Aho et al. [2006] explain very well how the bottom up

algorithm works. We are interested here in understand the basic principles

of the LALR(1) algorithm.

parsing tables

There are two tables in an LALR parser: The first one is the ACTION table,

the second is the GOTO table. The theoretical construction of these tables

can be found almost in any compiler literature such as Aho et al. [2006],

Kakde [2002], Terry [2000].

There are two methods for constructing LALR(1) parsing tables from the

LR(1) parsing tables: The first one, the easy but space consuming method, is

presented here. The other method differentiates from the former by checking

in every step of the construction of the LR(1) the simplification of the com-

mon rules, reducing significantly the number of states in the LR(1) parsing

table.

We explain the construction of the LALR(1) parsing tables and the con-

tent of the LR(1) through this example. Lets take this sample from the

grammar from Aho et al. [2006].

Simple Grammar Sample

S’ → S

S → CC

C → cC|d

From this grammar the parsing table LR(1) 2.1 is constructed according

to the algorithm presented in Aho et al. [2006]. This is called the canoni-

cal LR(1) collection. The symbol r in the table identifies a REDUCTION

operation and the symbol s identifies a SHIFT operation. The keyword acc

identifies the acceptance valid state.

From the table 2.1 we can observe that about half of the entries in the

table are blank spaces. The LR(1) parsing tables have the disadvantage of

Page 34: OMCCp: A MetaModelica Based Parser Generator Applied to ...

14 CHAPTER 2. THEORETICAL BACKGROUND

Table 2.1: LR(1) parsing table [Aho et al., 2006]

ACTION GOTOstate c d $ S C

0 s3 s4 1 21 acc2 s6 s7 53 s3 s4 84 r3 r35 r16 s6 s7 97 r38 r2 r29 r2

growing considerably large, even for small grammars, due to the redundancy

of productions for similar states with different lookahead symbol.

If we rearranged the rows in the way presented in the parsing table

2.2. We can notice that there are similarities between the productions for

different lookahead and the states (3 and 6 and 8 and 9). There are states

that share the same core production for different lookahead symbols.

Table 2.2: LR(1) parsing table rearranged [Aho et al., 2006]

ACTION GOTOstate c d $ S C

0 s3 s4 1 21 acc2 s6 s7 53 s3 s4 86 s6 s7 94 r3 r37 r35 r18 r2 r29 r2

The LALR(1) parsing table 2.3 is constructed in based on the one above

first by identifying the common core of each set and replacing the sets with

Page 35: OMCCp: A MetaModelica Based Parser Generator Applied to ...

2.2. ERROR HANDLING IN SYNTAX ANALYSIS 15

an union. For better understanding of this construction the reader can

address the literature [Aho et al., 2006, Section 4.7.4].

Table 2.3: LALR(1) parsing table [Aho et al., 2006]

ACTION GOTOstate c d $ S C

0 s3 s4 1 21 acc2 s6 s7 5

36 s36 s47 8947 r3 r3 r35 r1

89 r2 r2 r2

LALR(1) Algorithm

Both the LR(1) and the LALR(1) perform the same algorithm, the only

difference is the parsing tables used by LALR(1) contain different states

that will be Shifted or Reduced in the Stack.

The parsing algorithm starts by finding the right action in the ACTION

table for a given terminal symbol a and a current state i denoted AC-

TION[i,a]. This value can have either a REDUCE (r), SHIFT (s), ACCEPT

(acc) or error (blank) action.

The GOTO table is used to find the next state j and the non-terminal I

denoted GOTO[Ii, A] = Ij .

A REDUCE action takes a certain number of symbols from the parsing

stack, apply a transformation and puts back the result and the next state

back into the stack.

When an error is detected (blank entry in the parse table), several cor-

recting actions can be performed. This topic is covered with more detail in

Section 2.2.

2.2 Error Handling in Syntax Analysis

The Error handling techniques in the Front-End are more relevant during

the Syntax Analysis phase and the Semantic Analysis phase than in the

Page 36: OMCCp: A MetaModelica Based Parser Generator Applied to ...

16 CHAPTER 2. THEORETICAL BACKGROUND

Lexical Analysis phase.

Only a few errors can be detected by the Lexical Analysis, such as non-

terminated comments, invalid characters used or unrecognised token. One

possible error-recovery strategy implemented in a Lexer is to ignore invalid

characters from the input and keep the process.

The Error handling techniques can be divided into two topics: Error

recovery techniques and Error Message display. Error recovery techniques

are concerned on how the parser can keep parsing after an error token is

found. Error Message displays are related with how to present useful hints

for the developer in order to correct the source code.

In this section we will present the two topics named above for error

handling techniques during the Syntax Analysis phase.

2.2.1 Error Recovery

For LALR parsers several error recovery techniques have been developed as

in [Burke and Fisher Jr, 1982, Bilos, 1983, Burke and Fisher, 1987, McKenzie

et al., 1995, Degano and Priami, 1998, Corchuelo et al., 2002] and more

recent researches as in [Kats et al., 2009, de Jonge et al., 2010].

Error recovery techniques try to improve the quality of the parser by

different techniques such as primary recovery or secondary recovery.

The first condition to start the recovery is to access the configuration

obtained when the token preceding the error token was shifted onto the

stack. Techniques for deferring the reduce actions after a shift have been

developed in Burke and Fisher Jr [1982].

Primary techniques are related with single token modification from the

list of tokens. Single modification is only possible when the error is classified

as simple. This modification can be either insertion, deletion, substitution

or merging.

Every attempt to perform a repair is known as a trial. A common tech-

nique for searching the trials is to attempt to repair the error token by

performing one of these operations: merging, insertion, substitution, scope

recovery and finally deletion.

In the case of insertion or substitution a set of possible candidates should

be generated and then from there a single candidate or none should be

selected.

When the error requires more than a simple modification, the list of

Page 37: OMCCp: A MetaModelica Based Parser Generator Applied to ...

2.3. THE OPENMODELICA PROJECT 17

tokens needs to be reduced. This can be done by discarding tokens that

precedes, follows or surround the error token. This is known as secondary

recovery.

2.2.2 Error Messages

In simple recovery the error messages are classified in 5 different types:

merging, misspelling, insertion, deletion, substitution.

In secondary recovery the error messages are classified in 2 types. Type

1 error messages are displayed when the discarded tokens are present in

a single line. Type 2 errors are displayed when multiple lines need to be

discarded.

In addition there are 3 other types. The first refers to different candidates

for a recovery. The second type is displayed when the end of file is reached

but not expected. The third is used when all error recovery routines fail;

and then the parser displays a generic unrecoverable syntax error message.

2.3 The OpenModelica Project

OpenModelica2 is an open source project leaded by the Open Source Model-

ica Consortium (OSMC)3. At the moment of writing this report OpenMod-

elica is on version 1.7.0 launched on April 2011.

OpenModelica contains different tools that contribute with the design

and construction of simulation projects in OpenModelica. These tools are

classified into: Compiler tools, Graphic interface tools, Eclipse-based envi-

ronment.

The OpenModelica environment consists in several tools such as OMEd-

itor, UML-Modelica, OMShell, OMNotebook, DrControl under OMNote-

book and Modelica Development Tooling (MDT). There are some other

resources such as documentation, OMDev (tools for building the compiler),

and auxiliary tools for the OpenModelica Developer that have been used

during the development of this project. Figure 2.4 shows the architecture

of the OpenModelica environment.

2OpenModelica: http://www.openmodelica.org3OSMC: http://www.openmodelica.org/index.php/home/consortium

Page 38: OMCCp: A MetaModelica Based Parser Generator Applied to ...

18 CHAPTER 2. THEORETICAL BACKGROUND

OMOptimOptimization Subsystem

ModelicaCompiler

Interactivesession handler

Execution

Graphical ModelEditor/Browser

Textual Model Editor

ModelicaDebugger

DrModelicaNoteBook

Model Editor

Eclipse Plugin Editor/Browser

Figure 2.4: OpenModelica Environment [Fritzson et al., 2009]

2.3.1 The Modelica Language

The design of the Modelica Language was started in the fall 1996. The

first report of the language was made available on the web in September

1997. The first publication on Modelica by Elmqvist [1997] was made at the

Symposium on Computer-Aided control System Design is been developed

ever since, with several researcher contributors e.g. Fritzson and Bunus

[2002], Pop and Fritzson [2005, 2006], Akesson et al. [2008, 2010], Sjolund

[2009], Sjolund et al. [2011], Lundvall et al. [2009] as a language created

for multi-domain modelling and simulation. Modelica is an equation-based

and object-oriented language designed with the aim of defining a de facto

standard for simulation.

There have been recent efforts in writing a new Modelica compiler. The

compiler and other parts of the OpenModelica project are described in Fritz-

son et al. [2009].

2.3.2 MetaModelica extension

The main source of information for the MetaModelica language is the draft

document “MetaModelica users guide” written by Fritzson and Pop [2011a].

This document has been improved recently by Fritzson and Pop [2011b]

towards the implementation of the specifications of a new version of the

Page 39: OMCCp: A MetaModelica Based Parser Generator Applied to ...

2.3. THE OPENMODELICA PROJECT 19

Modelica Language.

MetaModelica was created in the OpenModelica project with the inten-

tion of modelling the semantics of the Modelica language. MetaModelica is

then the starting point for the construction of a Modelica Compiler. The

MetaModelica Language is part of the project to create a Bootstrapping

compiler written in MetaModelica for MetaModelica and Modelica language.

MetaModelica adds new operators and types to the Modelica language.

We cover in this report the constructs uniontype, record, matchcontinue and

list.

uniontype

The uniontype is a construct that allows MetaModelica to declare types

based on the union of 2 or more record types. It can be recursive and

include other uniontypes. An example of uniontype is presented in listing

2.1.

Listing 2.1: MetaModelica uniontype

1 uniontype Exp

record INT

3 Integer i n t e g e r ;

end INT ;

5 record IDENT

String i d ent ;

7 end IDENT;

end Exp ;

matchcontinue

The matchcontinue instruction resembles the switch instruction in C with

some additions. Unlike the switch instruction, matchcontinue can return a

value. It can contain more than one conditional, and it can also return more

than one value. A section for definition of local variables is present right

after the matchcontinue declaration. The wild card ‘ ’ (underscore) can be

used to match all cases, additionally an else case can be used instead of the

wild card.

The matchcontinue instruction contains case blocks similar as the com-

mon switch instruction in C code. Each case can contain an equation-block.

The program flow tries to execute correctly one instruction after the next

Page 40: OMCCp: A MetaModelica Based Parser Generator Applied to ...

20 CHAPTER 2. THEORETICAL BACKGROUND

one in a specific equation-block. If any instruction is not executed or fails,

the next case is tried. If it fails again then it keeps trying the next case

until one case block reaches the end. Then a return value is assigned to

the corresponding variables or case block can reach the final and no value

is assigned to the variables. An example of the syntax for matchcontinue is

presented in listing 2.2.

Listing 2.2: MetaModelica matchcontinue

2 ( token , env2 ) := matchcontinue ( act )

local

4 Types . Token tok ;

case (1 ) equation

6

tok = Types .TOKEN(tokName [ act ] , act , bu f f e r , i n f o ) ;

8 then (SOME( tok ) , env2 ) ;

case ( )

10 then (NONE( ) , env2 ) ;

else

12 then (NONE( ) , env2 ) ;

end matchcontinue ;

list

It is used to create linked list that works as in C. The bracket are used to

define the list elements. The operand ‘::’ is used to add items or to retrieve

items from a list.

To illustrate how a list works in MetaModelica, we have the following

sample code in listing 2.3. In this code the instruction on line 1 creates a

list called ‘a’. In the line 2 it retrieves the top element ‘3’ from the list ‘a’,

and saves it in the variable i. It saves the rest of the list back in the variable

‘a’. Finally we have the line 3 which is the inverse operation of line 2 and

will add an item ‘i’ into the list ‘a’.

Listing 2.3: MetaModelica list

1 l i s t<Integer> a ={1 ,2 ,3} ;

i : : a=a ;

3 a=i : : a ;

Page 41: OMCCp: A MetaModelica Based Parser Generator Applied to ...

2.3. THE OPENMODELICA PROJECT 21

2.3.3 Abstract Syntax Tree - AST

The AST (Abstract Syntax Tree) is is a structure that abstracts part of

the details present in the source code and represents unambiguously the

constructs of the programming language. The declaration of the AST (se-

mantic constructions of the language) is possible to be built in MetaModelica

language because of the construct ‘uniontype’ explained in the last section.

The construction of this tree is based in primitive operations such as

integer operations. These constructs represent the semantic constructs of

Modelica and MetaModelica language. The file Absyn.mo contains the spec-

ification for the constructs.

Page 42: OMCCp: A MetaModelica Based Parser Generator Applied to ...

22 CHAPTER 2. THEORETICAL BACKGROUND

Page 43: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Chapter 3

Existing Technologies

Several technologies were the base for the construction of this project. In

this chapter we present an introduction about some of the features that the

OpenModelica Compiler (OMC) has built-in and the current ANTLR parser

generator used in OMC.

Fast Lexical Analyzer Generator (FLEX) and GNU Bison are the tech-

nologies in which this project was based for the construction of the OMCCp.

Aaby [2003] is a good reference for those who want to learn more about

compilers construction with Flex and Bison. We use his book and the GNU

Bison manual (latest version today 2.4.3 by Donnelly and Stallman [2010])

to explain some technological aspects of FLEX and GNU Bison.

This chapter is not intended to be a guide for these technologies, but it

gives the reader the required concepts to understand the rest of this thesis.

3.1 OpenModelica Compiler (OMC)

OpenModelica Compiler (OMC) is the core tool for the OpenModelica project.

It has been developed since the beginning of the Modelica language. Fea-

tured in Fritzson et al. [2009].

3.1.1 Architecture and Components

The architecture of OMC is presented in Figure 3.1. The main components

of this diagram represent some of the phases of a compiler where the lexical

and syntax analysis is represented by the starting process “Parser”. This

23

Page 44: OMCCp: A MetaModelica Based Parser Generator Applied to ...

24 CHAPTER 3. EXISTING TECHNOLOGIES

parser does both, the lexical and the syntax analysis due to the design of

ANTLR as an integrated lexer and parser generator.

SCode/explode

Lookup

Parse DAELowInst

Ceval

Static

Absyn SCode DAE

(Env, name) SCode.Class

Exp.Exp

Values.Value

SCode.Exp(Exp.Exp,

Types.Type)

(Env, name)

Main

SimCode

C code

DumpDAEFlat Modelica

Figure 3.1: OMC simplified overall structure [Fritzson et al., 2009]

The OMC is used to compile both, MetaModelica grammar and Modelica

grammar from version 1 until 3 (see Fig 3.2). Its source code is available

for download from the subversion repository1.

OMC Compiler

MetaModelicaParser Modelica1Parser Modelica2Parser Modelica3Parser

Figure 3.2: OMC Language Grammars

3.1.2 ANTLR

Another Tool for Language Recognition (ANTLR) is a parser generator tool

that integrates the lexical analysis and the syntax analysis in one single tool.

1OpenModelica Subversion: svn co https://openmodelica.org/svn/OpenModelica/trunk/

Page 45: OMCCp: A MetaModelica Based Parser Generator Applied to ...

3.1. OPENMODELICA COMPILER (OMC) 25

It generates parsers for LL(k) grammars.

ANTLR was created by Parr and Quong [1995]. ANTLR is today in

version 3. The information presented here is extracted from the official

website2 and the tutorial website by Mills [2005]. The reference manual

by Parr [2007] is a more complete and detailed information about ANTLR.

This project is intended to be a substitute for this tool. We consider impor-

tant for this project to get an overview of the most significant features and

characteristics of this tool.

The grammar used in ANTLR is of type LL(k), which means that the

parsers generated by ANTLR are Top-Down parsers as explained in Sec-

tion 2.1.3. ANTLR uses Extended Backus-Naur Form (EBNF) notation for

defining the grammar rules. The notation Extended Backus-Naur Form is

an extension of Backus-Naur Form (BNF). EBNF notation adds new con-

structs to the BNF such as ‘+’ to indicate one or more of an item after

square brackets.

The grammar file used by ANTLR contains several parts as presented in

listing 3.1.

Listing 3.1: ANTLR grammar file structure

1 header {// s t u f f that i s p laced at the top o f <a l l > generated f i l e s

3 }

5 opt ions { opt ions for e n t i r e grammar f i l e }

7 { op t i ona l class preamble − output to generated c l a s s f i l e

immediately be f o r e the d e f i n i t i o n o f the class }9 class YourLexerClass extends Lexer ;

// d e f i n i t i o n extends from here to next c l a s s d e f i n i t i o n

11 // ( or EOF i f no more c l a s s d e f s )

opt ions { YourOptions }13 tokens {

EXPR; // Imaginary token

15 THIS=” that ” ; // L i t e r a l d e f i n i t i o n

INT=” i n t ” ; // L i t e r a l d e f i n i t i o n

17 }

19 l e x e r r u l e s . . .

myrule [ a rgs ] r e tu rn s [ r e t v a l ]

21 opt ions { de fau l tEr ro rHand le r=fa l se ; }

2ANTLR: http://www.antlr.org/

Page 46: OMCCp: A MetaModelica Based Parser Generator Applied to ...

26 CHAPTER 3. EXISTING TECHNOLOGIES

: // body o f r u l e . . .

23 ;

25 { op t i ona l class preamble − output to generated c l a s s f i l e

immediately be f o r e the d e f i n i t i o n o f the class }27 class YourParserClass extends Parser ;

opt i ons { YourOptions }29 tokens . .

pa r s e r r u l e s . . .

31 rulename [ args ] r e tu rn s [ r e t v a l ]

opt i ons { de fau l tEr ro rHand le r=fa l se ; }33 { op t i ona l i n i t i a t i o n code }

: a l t e r n a t i v e 1

35 | a l t e r n a t i v e 2

. . .

37 | a l t e r n a t i v e n

;

39

{ op t i ona l class preamble − output to generated c l a s s f i l e

41 immediately be f o r e the d e f i n i t i o n o f the class }class YourTreeParserClass extends TreeParser ;

43 opt ions { YourOptions }tokens . . .

45 t r e e par s e r r u l e s . . .

47 // a r b i t r a r y l e x e r s , p a r s e r s and t r e e p a r s e r s may be inc luded

As we can see, it contains several sections including a header, lexer (to-

kens and rules), parser (tokens and rules), AST rules and options sections

that are copied verbatim to the generated parser.

The generated parser files are in the desired target-language that is spec-

ified when compiling the grammar file.

ANTLR allows the OpenModelica developers to specify in a robust and

flexible way the rules and the grammar for the combination of the lexer

and parser. It then generates code in the target language that outputs the

designed AST for both Modelica and MetaModelica grammar.

3.1.3 Current state

The OMC is today (May 2011) in the version 1.7.0 (r8600). It is intended

to be used by both industry and academy. Various research materials have

Page 47: OMCCp: A MetaModelica Based Parser Generator Applied to ...

3.2. FLEX 27

been produced since 1997 including: Master’s3 and PhD’s4 thesis, confer-

ence papers5, journals papers6 and books7. Other more are today under

development or recently finished such as this master’s thesis. This proves

that the OMC is today an active research topic in the OpenModelica project.

3.2 Flex

Based in the tool called Lexical Analyzer Generator (LEX). The grammar

accepts regular expressions to define the tokens.

3.2.1 Input file lexer.l

The FLEX input file lexer.l contains three sections: definitions, rules and

user code.

Listing 3.2: Flex file structure

1 D e f i n i t i o n s

%%

3 Rules

%%

5 User code

Definitions: Contains declarations of definitions and start conditions. Can

contain code to be included verbatim to the output in the top as a

declaration.

Rules: Contains the rules in the form of patterns of and extended set of

regular expressions. Each rule contains an action in C code that can

return a token, reject or change the start condition.

User Code: It is copied verbatim to the output file.

3.2.2 Output file lexer.c

The output file lexer.c generated by FLEX contains three main sections:

Declaration of variables and arrays, the algorithm that runs the DFA and

3http://www.openmodelica.org/index.php/research/master-theses4http://www.openmodelica.org/index.php/research/phd-and-licentiate-theses5http://www.openmodelica.org/index.php/research/conference-papers6http://www.openmodelica.org/index.php/research/journal-papers7http://www.openmodelica.org/index.php/research/booksproceedings

Page 48: OMCCp: A MetaModelica Based Parser Generator Applied to ...

28 CHAPTER 3. EXISTING TECHNOLOGIES

the return action section with the actions that have been specified for each

rule.

The arrays that are present in the lexer are:

yyec: Mach any UTF-8 code with a started condition.

yyaccept: check the states against the accept condition.

yyacclist: once accepted, the action for each state is found here.

yymeta: control array for the transitions.

yybase: control array for the transitions.

yydef: default transition for the states.

yynxt: determines the next transition of the states.

yychk: control array that verifies errors.

FLEX is designed to handle a large amount of rules and tokens. It

simplifies the number of rules and tokens utilized by the parser in the next

phase of the compiler. That is why it is common to find a combination

of FLEX and other parser generators such as the tool called Yet Another

Compiler-Compiler (YACC) or its successor GNU Bison.

For a complete reference of FLEX, the FLEX manual by Paxson [2002]

is a good source of information.

3.3 GNU Bison

GNU Bison is a parser generator that generates a LALR(1) parser from a

context-free grammar. The generated parser can be in one of these three

languages: C-code, C++ and Java. It is based on the tool called YACC.

GNU Bison receives as an input a file with the grammar rules. This

grammar file is specified using BNF. The output of the process is a parser

written in C that communicates with a lexer, commonly written in LEX or

FLEX.

In this section we explain these input and output file in detail and cover

some other details about GNU Bison that will increase the understanding

of the presented project implementation in the next chapter.

Page 49: OMCCp: A MetaModelica Based Parser Generator Applied to ...

3.3. GNU BISON 29

3.3.1 Input file parser.y

There are 4 sections in a grammar file: Prologue, Bison declaration, Gram-

mar rules and Epilogue distributed as presented in Listing 3.3.

Listing 3.3: Bison file structure

1 %{Prologue

3 %}Bison d e c l a r a t i o n s

5 %%

Grammar r u l e s

7 r e s u l t : ru le1−components . . .

| ru le2−components . . .

9 . . .

;

11 %%

Epi logue

Prologue: Macro definitions, declarations of functions, variables used in

the grammar rules. It is attached verbatim to the beginning of the

generated file.

Declarations: Define terminal, nonterminal symbols and specify prece-

dence.

Grammar rules: Rules expressed as result of composition of rules and

defines an action for each rule in Backus-Naur Form (BNF) notation.

Epilogue: is attached to the generated file at the end as the prologue in

the beginning.

Each section is separated by a specific token, the prologue uses ‘%}’ and

the other sections use ‘%%’.

3.3.2 Output file parser.c

GNU Bison generates a file that contains C source code. In generated file

we identify four main parts: Declarations of variables and transition arrays;

the algorithm that runs the PDA; the response actions that build the AST

tree while doing the reductions; and a section for custom code inserted by

the developer.

Page 50: OMCCp: A MetaModelica Based Parser Generator Applied to ...

30 CHAPTER 3. EXISTING TECHNOLOGIES

Transition arrays

Aho et al. [2006] presents the algorithm for LALR(1) based on the creation

of two dimensional parsing tables called ”ACTION table” and ”GOTO ta-

ble” as presented in Section 2.1.4. GNU Bison improves the efficiency of

the storage by converting these two dimensional tables in arrays using the

algorithm method described by Tarjan and Yao [1979].

Popuri [2006] presents a detailed analysis of the role of each array in the

generated file. The 15 arrays generated by GNU Bison are:

yytranslate: interface with the lexer to understand the tokens of the lexer

in the internal representation of the parser.

yyrhs: list of symbol numbers of all rules. yyrhs[n]= first symbol on the

RHS of the rule.

yyprhs: index in yyrhs of the first rhs symbol of each rule.

yyrline: line number in the grammar file where the rule is defined.

yytname: list of names of defined symbols.

yytoknum: list of value of the tokens in the lexer.

yyr1: specifies the symbol number for each rule.

yyr2: number of tokens to be reduced for a certain rule.

yydefact: default reduction for each state

yydefgoto compressed GOTO table, each entry specifies the state to tran-

sition to each non-terminal.

yytable: state numbers in a pre-calculated order, works together with yy-

check, yypgoto and yypact to indicate the next state and the rule to

be use for a reduction.

yypact: indicate what to do next, work together with yytable.

yypgoto: indicates anomalies that derive in errors.

yycheck: a control table that matches the current rule that guides to the

discover of anomalies in the parser.

Page 51: OMCCp: A MetaModelica Based Parser Generator Applied to ...

3.3. GNU BISON 31

As a summary the array yytranslate is as it names indicates a translator

between the lexer and parser. The arrays yydefact, yydefgoto, yyr1, yyr2,

yytable, yypgoto, yypact and yycheck are used to represent the LALR(1)

parsing tables ACTION and GOTO. The other arrays are helpers for de-

bugging and printing.

LALR algorithm

GNU Bison uses the function yyparse to start the parsing operation. It

makes use of two stacks, one for the states and one more for the reductions

and the construction of the AST that is called parser stack.

The algorithm starts by reading a token and pushing the value into the

parser stack, this operation is called SHIFT. When the stack accumulates

enough elements to match a rule the elements are popped from the parser

stack and converted into a new symbol, which is the result action of the rule,

this operation is called REDUCE. This result is pushed back again into the

parser stack. In each step the parser computes the next state based on the

arrays presented before and pushes or pops at the same time as the SHIFT

and REDUCE actions are performed over the parser stack.

GNU Bison includes two new symbols into its internal symbol configura-

tion, the token accept and end are added to identify when the parser stops

and when it finish in an acceptance state.

Construction of the AST

The AST is constructed by the REDUCTIONS actions. The AST can be

specified in the section of the grammar file for the grammar rules; specifically

where the description of the actions for the construction are placed.

Error handling

GNU Bison uses a single primary recovery technique based on the activation

of an error flag that tells the parser to suppress the syntax error diagnostic

while recovering from an error. A developer can write specific rules for the

special token error that can help the parser to detect easily the presence of

errors. There is a chapter in the reference manual of GNU Bison that can

give a more detailed overview of the error handling.

Page 52: OMCCp: A MetaModelica Based Parser Generator Applied to ...

32 CHAPTER 3. EXISTING TECHNOLOGIES

Other considerations about BISON

The parser generated by C manage the memory in an efficient way to avoid

memory exhaustion specially in situations when too many tokens have been

shifted without a reduction operation. This operation is done inside the

parser and usually a developer does not need to configure anything, al-

though the parameters called YYMAXDEPTH and YYINITDEPTH can

be modified.

The GNU Bison parser generator supports the generation of code in

three programming languages: Java, C and C++.

A table of symbols is provided in the GNU Bison manual [Donnelly and

Stallman, 2010, Appendix A] that allows better understanding of the code

inside the generated parsers. However the article written by Popuri [2006]

explains in detail the structures, arrays and makes internal comments in

specific part of the code that clarifies more the algorithm used by GNU

Bison. Some examples of the interaction of FLEX and GNU Bison are

presented in Aaby [2003].

Page 53: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Chapter 4

Implementation

4.1 Proposed Solution

This chapter presents the results of this project, which are the design and

implementation of a MetaModelica Lexer and Parser Generator written in

the MetaModelica Language that has been named as the OpenModelica

Compiler-Compiler parser generator (OMCCp) 1.

We present in this chapter a description of the design and architecture

of the parser generator proposed in this report. We cover at the end the

description of the error handling techniques used in OMCCp and the inte-

gration into the OpenModelica Compiler (OMC).

First we start by outlining the main characteristics that describe this

solution:

• It is a tool written entirely in MetaModelica language.

• Includes a Lexer and a Parser LALR(1) Generator that generate Meta-

Modelica code.

• The Lexer is based on the existing tool FLEX for the generation of

the transition tables for the DFA.

• The Parser is based on the existing tool BISON for the generation of

the transition tables for the Deterministic Push-down Automata.

1OMCCp was initially named OMCC. This explains why the design figures and somefiles in the project use the name OMCC instead of OMCCp. Whenever OMCC is presentit may be interpreted as OMCCp.

33

Page 54: OMCCp: A MetaModelica Based Parser Generator Applied to ...

34 CHAPTER 4. IMPLEMENTATION

• The error handler is based on a primary recovery technique, and the

generation of a candidate set that is properly displayed to the devel-

oper.

Section 4.2 presents the design of the solution, section 4.3 explains how

the generation of files is performed by OMCCp. We continue explaining the

error handling techniques utilised in OMCCp in Section 4.4 and at the end

in Section 4.5 we explain the integration with the OMC.

Appendix A covers the basic command line instructions for running the

OMCCp that generates the files, and the instructions to run the generated

parser for the grammar specified.

4.2 OMCCp Design

Figure 4.1 presents an overview of OMCCp. The Parser and Lexer Generator

are based on the C files generated by FLEX and BISON from the grammar

files lexer.l and parser.y.

OMCC

«subsystem»LexerGenerator

«subsystem»ParserGenerator

Lexer[Suffix].moLexTable[Suffix].mo

LexCode[Suffix].mo Token[Suffix].mo

Parser[Suffix].mo ParseTable[Suffix].mo

ParseCode[Suffix].mo

FlexBison

Required files:Parser.yLexer.lLexer.moParser.moLexCode.tmoParseCode.tmo

INPUT FILES

OMCC

GENERATED FILES

Lexer[Suffix].c Parser[Suffix].c

Figure 4.1: OMCCp (OpenModelica Compiler - Compiler) Lexer and ParserGenerator

Page 55: OMCCp: A MetaModelica Based Parser Generator Applied to ...

4.2. OMCCP DESIGN 35

Those files are c-code generated and contain three main parts that con-

stitute the lexer and the parser generated. We can identify: a section with

the transition arrays, a section with the machine that runs the algorithm

for the lexer or parser and finally an action resolution section. The last

section contains the return token action for the lexer and a reduction/AST

construction action for the parser.

Based on the identification of the main parts of each generated file, the

design presented in figure 4.2 shows the different components of the solu-

tion. We can identify two principal package called LexerGenerator.mo and

ParserGenerator.mo which are responsible for the generation of the com-

plete Compiler-Compiler in MetaModelica code.

4.2.1 Lexical Analyser

The design of the Lexer is presented in figure 4.3. The Lexer contains 3

main files that were designed with the aim of separating: the parsing tables,

the DFA and the action code. The tables for the transitions of the states are

loaded at the start of the DFA. Once the DFA identifies the rule, it passes

the control to the code file that takes the action and decides which token

to return to the DFA. The DFA pushes the result returned into the list of

tokens.

The Lexical Analyser uses the built-in functions from System.mo and

Util.mo files that are part of the compiler. A new file was developed,

Types.mo, to support the uniontype Token and the records TOKEN and

INFO that are used for both, the lexer and the parser.

Lexer.mo

The file Lexer.mo implements the DFA for the Lexical Analysis as explained

in Section 2.1.2. It is the main file of the Lexer and makes the calls to the

functions in the other files LexerCode.mo and LexTable.mo that constitute

the lexer. Its main function is to load the source code file and recognise all

the tokens described by the grammar. It returns as an output to the parser

either a list of tokens or an error if no tokens were found or some characters

in the source code are not compliant with the 8-bytes encoding format called

UTF-8.

In the process of loading the file, it converts the source code file into an

Page 56: OMCCp: A MetaModelica Based Parser Generator Applied to ...

36 CHAPTER 4. IMPLEMENTATION

OMC

+sca

n(i

n p

rogr

am, o

ut

toke

ns)

-lo

adSo

urc

eCo

de(

)+s

can

Stri

ng(

)+l

ex()

-co

nsu

me(

in p

rogr

am, i

n e

nv,

ou

t to

ken

s)-e

valS

tate

(in

ou

t en

v)-f

ind

Ru

le(i

no

ut

env)

+get

Info

()

-EN

V-L

exer

Tab

le-p

rogr

am

Lexer.mo

+gen

erat

eLex

er()

: Le

xTab

le.m

o+b

uild

Lexe

r()

+bu

ildTa

ble

s()

+bu

ildC

od

e()

LexerGenerator.mo

+printToken()

+getMergeToken()

+printErrorToken()

+printTokens()

-To

ken

-In

fo

«ty

pe»

OMCCTypes.mo

-Lex

erTa

ble

«ty

pe»

LexTab

le.m

o

-lis

t<In

tege

r>p

rogr

am

«u

tilit

y»Util.mo

+Par

se(i

n t

oke

ns)

-pro

cess

Toke

n()

-red

uce

(in

sta

ck)

-tra

nsl

ate(

)+e

rro

rHan

dle

r()

+ad

dSo

urc

eMes

sage

()+c

hec

kCan

did

ates

()+c

hec

kTo

ken

()+g

etTo

ken

Sem

Val

ue(

)+p

rin

tCan

did

ateT

oke

ns(

)

-Par

seTa

ble

-En

viro

men

t-l

ist<

Toke

ns>

toke

ns

-set

tin

gs

Parser.mo -A

ST

«ty

pe»

Absyn.m

o

«ca

ll»

+gen

erat

ePar

ser(

)-b

uild

Co

de(

)-b

uild

Tab

les(

) : L

exTa

ble

.mo

-bu

ildP

arse

r()

-bu

ildTo

ken

s()

ParserGenerator.mo

«d

eriv

ed»

«u

ses»

«u

ses»

«u

ses»

«u

ses»

+mai

n(i

n a

rgs)

NewParser.mo

«u

ses»

«u

ses»

«u

ses»

-Par

seTa

ble

«ty

pe»

ParseTable.m

o

+act

ion

(in

act

ion

: in

t)

-EN

V

LexerCode.m

o

«u

ses»

+act

ion

Red

uce

()+p

ush

()+g

etA

ST()

+in

itia

lizeS

tack

()-r

edu

ceSt

rin

gSta

ck()

-get

Info

()

-Mu

ltiT

yped

Stac

k

ParseCode.m

use

//

call

the

lexe

rto

ken

s =

Lexe

r.sc

an(f

ilen

ame)

; //

cal

l th

e p

arse

ras

t =

Par

ser.

par

se(t

oke

ns)

;

«d

eriv

ed»

+rea

dFi

le()

+wri

teFi

le()

+str

ingO

per

atio

ns(

)

«u

tilit

y»System.m

o

-To

ken

Co

de

«ty

pe»

Tokens

-ad

dEr

ror

Error.mo

Figure 4.2: OMCCp Lexer and Parser Generator Architecture Design

Page 57: OMCCp: A MetaModelica Based Parser Generator Applied to ...

4.2. OMCCP DESIGN 37

-LexerTable

«type»LexTable.mo

-*AllTokens

«type»list<Token>tokens

+action(in action : int, out tokens)

-ENV

LexerCode.mo

System.mo Util.mo

+name+value+col : int+row : int

«type»Token

-list<Integer> program

«type»Program

+scan(in program, out tokens)-loadSourceCode()+scanString()+lex()-consume(in program, in env, out tokens)-evalState(inout env)-findRule(inout env)+getInfo()

-ENV-LexerTable-program

Lexer.mo«send»

Figure 4.3: OMC-Lexer design

array of integers, each integer representing the UTF-8 code for the character

present in the source code, e.g. the character ‘a’ will be the UTF-8 code 61.

This helps the lexer to increase the speed in the process of recognising the

tokens due to the direct mapping between the UTF-8 code and the position

in the transition array used for the lexer.

For recognizing the tokens, Lexer.mo runs a DFA based on the transition

arrays found in LexTable.mo. When it reaches an acceptance state it calls

the function action in the LexerCode.mo file. And finally it returns a list of

tokens that are the input for the parser.

The entrance function to the Lexer is named scan, and it is defined in

Lexer.mo:

Listing 4.1: Lexer.mo function scan

function scan ”Scan s t a r t s the l e x i c a l ana l y s i s , load the t a b l e s

and consume the program to output the tokens ”

2 input String f i leName ” input source code f i l e ” ;

input Boolean debug ” f l a g to a c t i v a t e the debug mode” ;

4 output l i s t<Types . Token> tokens ” re turn l i s t o f tokens ” ;

The complete file Lexer.mo is available in Appendix B.1

Page 58: OMCCp: A MetaModelica Based Parser Generator Applied to ...

38 CHAPTER 4. IMPLEMENTATION

LexTable.mo

The LexTable.mo file is the source of the Lexer.mo file for performing the

transitions to new states and finding the tokens out of the input stream. It

contains two variables and 8 arrays that are extracted from the file generated

by FLEX.

The two parameters are utilised to perform control instructions in the

Lexer.mo file and are yy limit and yy finish. The parameter yy finish is

specially used to detect the end of a token.

The 8 arrays that are used to perform the task of the DFA are yy accept,

yy ec, yy meta, yy base, yy def, yy nxt, yy chk and yy acclist. All the arrays

are utilised in the file Lexer.mo, but only the most significant arrays will be

explained in this report. Those are: yy ec, yy accept and yy acclist.

The first array used is yy ec, this array contains all the UTF-8 codes and

the initial state of each character when consuming the input stream by the

DFA.

After performing a mathematical checking operation over the current

character; the DFA uses the yy accept array to find if the current state is a

valid acceptance state and continues until it determines that the lookahead

character belongs to another token. Then it performs a roll-back operation

to the last acceptance state in the stack. Following this the DFA uses the

yy acclist to determine the return token; which is a call to a function in the

LexerCode.mo file.

The generation of this file is explained in Section 4.3.1. A complete

sample of the generated file LexTable10.mo is available in Appendix E.4

LexCode.mo

The file LexCode.mo contains all the specific actions that the lexer performs

when a token has been recognised. The actions that can be perform are

one of these three possible actions: ignore token, return a specific token or

change to another DFA.

The first action is to ignore the token, this operation is performed by

the lexer when a space, line feed or a block of comment is been found in

the input stream. The tokens ignored by the lexer simplifies the job of

the parser, because those tokens are not used for any construction in the

grammar, therefore they will not be converted into executable code in the

further phases of the compiler.

Page 59: OMCCp: A MetaModelica Based Parser Generator Applied to ...

4.2. OMCCP DESIGN 39

The second possible action that can be done when a token is been recog-

nised is to return a specific token, the code of the action defines the token

to be returned. Some information is collected together with the token in a

RECORD called TOKEN that allows the parser to identify the line and the

position of the token in the original source code file.

The last and third action that this function does is to switch from one

DFA to another one. This operation is performed in certain situations, e.g.

when the DFA finds a starting comment block ‘/*’, and all the subsequent

tokens are required to be ignored or categorised as a different token, e.g. in

the case of recognising strings. For this action a new starting state is set

up in the machine and the new characters run in a different DFA as the

original. After the end token is found (e.g. ‘*/’) then the start state returns

to the original one.

This file is generated from the lexer.c file which is produced by FLEX,

the generation of this file is explained in Section 4.3.1. A complete sample

of the generated file LexerCode10.mo is available in Appendix E.5.

4.2.2 Syntax Analyser

The Parser design for OMCCp is presented in figure 4.4, it carries the

function of performing the syntax analysis of the compiler.

+printToken()+getMergeToken()+printErrorToken()+printTokens()

-Token-Info

«type»OMCCTypes.mo

+Parse(in tokens)-processToken()-reduce(in stack)-translate()+errorHandler()+addSourceMessage()+checkCandidates()+checkToken()+getTokenSemValue()+printCandidateTokens()

-ParseTable-Enviroment-list<Tokens>tokens-settings

Parser.mo

-AST

«type»Absyn.mo

«uses»

«uses»

«uses»

-ParseTable

«type»ParseTable.mo

+actionReduce()+push()+getAST()+initializeStack()-reduceStringStack()-getInfo()

-MultiTypedStack

ParseCode.mo«uses»

«call»

-TokenCode

«type»Tokens

-addError

Error.mo

«send»

AST

ErrorMessages

Figure 4.4: OMC-Parser design

Page 60: OMCCp: A MetaModelica Based Parser Generator Applied to ...

40 CHAPTER 4. IMPLEMENTATION

The design of the parser is split in different files, similar as the lexer,

to separate the logic of the PDA (Parser.mo) from the predictive tables

(ParseTable.mo) and the Shift-Reduction actions that are used in the con-

struction of the AST (ParseCode.mo). Additionally a file that connects the

lexer with the parser is utilised to keep consistency with the token codifi-

cation (Token.mo). The way these files interact can be seen in Figure 4.4.

The interaction of the different components is split in different files and

explained in this section.

Tokens

ParsingTables

OMCLALR(1)PARSERMultiTyped

StackStateStack

Shift/Reduce Error Handling

AST

Figure 4.5: OMC-Parser LALR(1)

Token.mo

The file Token.mo contains the complete list of tokens utilised by the gram-

mar with their respective code. This file is the link between the lexer and

the parser, it is used by both of them to identify in the same way the to-

kens. When the parser receives the token code from the lexer, it performs a

translation into local codes that are only used by the parser to simplify the

addressing in the predictive arrays. This operation is done by using as index

the new code assigned by the parser to the token. Each token is defined as

a type constant Integer.

A complete sample of the generated file Token10.mo is available in Ap-

pendix E.3

Page 61: OMCCp: A MetaModelica Based Parser Generator Applied to ...

4.2. OMCCP DESIGN 41

Parser.mo

The file Parser.mo implements the PDA for the Parser as explained in

Section 2.1.3. In this file we find the implementation of the LALR(1)

algorithm previously explained in Section 2.1.4.

The main function of Parser.mo is to efficiently convert a list of tokens

received by the Lexer into the AST described in the Absyn.mo file. For

performing this task, Parser.mo utilizes the Predictive Parse Tables located

in the file ParseTable.mo to perform the Reduce-Shift actions calls that are

located in the file ParseCode.mo.

The external interface of the parser is a function called “parse” described

here:

Listing 4.2: Parser.mo function parse

function parse ” r e a l i z e the syntax a n a l y s i s over the l i s t o f

tokens and gene ra t e s the AST t r e e ”

2 input l i s t<Types . Token> tokens ” l i s t o f tokens from the l e x e r ”

;

input String f i leName ” f i l e name o f the source code ” ;

4 input Boolean debug ” f l a g to output debug messages that

exp la in the s t a t e s o f the machine whi l e par s ing ” ;

output Boolean r e s u l t ” r e s u l t o f the par s ing ” ;

6 output ParseCode . AstTree as t ”AST t r e e that i s returned when

the r e s u l t output i s t rue ” ;

The complete file Parser.mo is available in Appendix C.1

ParseTable.mo

The ParseTable.mo file contains the arrays that allows the Parser.mo to

run the PDA and performs the Shift-Reduce actions. It contains 10 integer

constants and 15 arrays extracted from the file parser.c, which is generated

by BISON.

In this section we will cover only the most significant arrays that are used

by the parser. More detailed explanation can be found in Popuri [2006].

As explained before, when the parser reads the code of the token from

the lexer, it is required to performs a translation into local codes, the array

yytranslate contains the converted code for each original code in the lexer.

The numeration of the tokens starts at the index 3, the first 2 positions are

used for the reserved tokens ”error” and ”$undefined”. If the token is an

Page 62: OMCCp: A MetaModelica Based Parser Generator Applied to ...

42 CHAPTER 4. IMPLEMENTATION

UTF-8 character the table yytranslate contains the corresponding UTF-8

code. Otherwise the numeration starts after the index position 255.

Once the token is being read by the lexer, it starts the algorithm that

queries the yypact array. This determines the required action over the input,

based on the current state and the current token code. Similar as the table

ACTION in LALR parsing.

The array yypact can contain positive or negative values. Positive values

indicates that a Shift action must be done and negative values indicates that

a Reduce action should be done. If the required action is Shift, then the

PDA pushes the value obtained into the state stake. If the required action

is a Reduce operation then array yydefact is queried to catch possible errors

over the input. The constants YYPACT NINF and YYTABLE NINF are

used to identify the errors in the corresponding arrays yypact and yytable

and forward them to the error handler function.

During the Reduce operations the array yyr2 is queried to find the num-

ber of tokens to reduce and the arrays yyr1,yypgoto,yytable,yydefgoto are

used similar to the GOTO table in LALR parsing. These operations are

send to the function ‘actionRed’, located in the file ParseCode.mo to con-

struct the AST.

The auxiliary arrays yytoknum,yytname are used to identify the token

codes and names.

A complete sample of the generated file ParseTable10.mo is available in

Appendix E.1

ParseCode.mo

The file ParseCode.mo contains the specific Reduce operations that each

grammar performs when a certain rule matches the input tokens. The main

function of this file is to handle the MultiTypedStack that is used by this

parser to construct the AST. One of the difficulties that was found during

the development of this part was the required strict-typed structure of the

AST. This difficulty was overcame with the use of a MultiTypedStack, which

handles the reduce operations requested by the LALR parsing algorithm.

To explain how it works, we refer to Section 2.1.4 where the LALR

algorithm is explained. Lets assume that we have a grammar that has 3

different types. The first one and the second one are the primitive types

Integer and String, and the third one is a new type called Absyn.Exp.

Page 63: OMCCp: A MetaModelica Based Parser Generator Applied to ...

4.2. OMCCP DESIGN 43

The MultiTypedStack contains one stack per each type found in the gram-

mar specification and it is defined in MetaModelica language as presented

here:

Listing 4.3: MultiTypedStack AstStack

uniontype AstStack

2 record ASTSTACK

l i s t<Absyn . Exp> stackExp ;

4 l i s t<String> s t a c k S t r i n g ;

l i s t<Integer> s t a c k I n t e g e r ;

6 end ASTSTACK;

end AstStack ;

When the parser finds a Shift operation it calls the ‘function push’ on

this file which will push a String value into the stackString. During the

reduce operation the parser needs to know which stack to use for each of

the constructions of the AST. The way this MultiTypedStack works can be

explained in the following example that presents the reduce operation, the

build of the AST operation and finally a push back into the stack of the

construction build as part of AST.

In the listing 4.4 the reduction takes three item from the three different

stacks and constructs an Absyn.ALGORITHMITEM object. After this it

pushes back the result into the stack for the Absyn.Algorithm type called

skAlgorithmItem.

Another feature that can be useful for the reductions is the use of the

info keyword. In the listing 4.4, we can observe that the instruction four

uses a stack called skToken to retrieve the token information. The token

information returns a info token of type Absyn.Info which contains the com-

bined information of the first and the last token in the stack that are used for

this reduction. This makes possible for the developer to insert information

about location that can be used later in the other phases of the compiler.

Listing 4.4: ParseCode.mo case reduce action

1 case (57 , ) // #l i n e 344 ” parserMode l i ca . y”

equation

3 // reduce

( in fo , skToken ) = g e t I n f o ( skToken , mm r2 [ act ] ) ;

5 v3Str ing : : s kS t r ing = skSt r ing ;

v2Comment : : skComment = skComment ;

7 v1Algorithm : : skAlgorithm = skAlgorithm ;

Page 64: OMCCp: A MetaModelica Based Parser Generator Applied to ...

44 CHAPTER 4. IMPLEMENTATION

// bu i ld

9 vAlgorithmItem = Absyn .ALGORITHMITEM( ( v1Algorithm ) ,

SOME( ( v2Comment) ) , i n f o ) ;

// push Result

11 skAlgorithmItem= vAlgorithmItem : : skAlgorithmItem ;

13 then ( ) ;

One final task that can be found in this file is the function getAST, which

returns to the parser the result of the AST tree. The listing 4.5 shows the

interface of the function getAST implemented in MetaModelica code.

Listing 4.5: ParseCode.mo function getAST

1 function getAST ” re tu rn s the AST b u i l t by the par s ing ”

input AstStack astStk ”MultiTypedStack used by the par s e r ” ;

3 output AstTree as t ” r e tu rn s the AST in the f i n a l type o f the

t r e e ” ;

A complete sample of the generated file ParseCode10.mo is available in

Appendix E.2.

4.3 OpenModelica Compiler-Compiler Parser

(OMCCp)

OpenModelica Compiler-Compiler parser generator (OMCCp) is the tool

implemented in this thesis that generates a Lexer and Parser in MetaMod-

elica language based in the grammar files specified in BNF.

OMCCp is composed by two packages, the first is the Lexer Generator

and the second is the Parser Generator. Both of them will be explained in

this section.

4.3.1 Lexer Generator

The Lexer Generator for OMCCp is implemented in the file LexerGenera-

tor.mo. It receives as an input the file lexer.c generated by FLEX introduced

in Section 3.2. The FLEX file contains the required information to be used

by the file Lexer.mo explained in Section 4.2.1.

For the generation of the files, a suffix for the name of the files gen-

erated is required. We encourage the name of the language as a suffix

Page 65: OMCCp: A MetaModelica Based Parser Generator Applied to ...

4.3. OPENMODELICA COMPILER-COMPILER PARSER (OMCCP)45

for the generated files, although it is not restricted. There are three files

generated by the Lexer Generator: Lexer[Suffix].mo, LexTable[Suffix].mo,

LexerCode[Suffix].mo.

By design, all the generated files by OMCCp will include the suffix after

its name to avoid equal names for different languages parsers. For example,

if the language grammar is Modelica the generated files will be LexerMod-

elica.mo, LexTableModelica.mo, LexerCodeModelica.mo.

For all the files generated, the Lexer Generator adds a time comment in

the beginning of the file which allows a developer to identify the date and

time when the file was created. This also happens with all the files genereted

by the Parser Generator.

Generation of Lexer[Suffix].mo

The generation of the file Lexer[Suffix].mo does not require any search on the

file generated by FLEX. The Lexer Generator makes a copy of the original

Lexer.mo and changes some of the values that address the other files in the

parser, for example LexTable turns into LexTable[Suffix], LexerCode turns

into LexerCode[Suffix] and additionally it change the name of the package

to Lexer[Suffix].

Generation of LexTable[Suffix].mo

The generation of the file Lexer[Suffix].mo requires a search in the first sec-

tion identified in the file lexer.c generated by FLEX. The regular expression

function regex provided by the included file System.mo is used to match the

declaration of arrays and variables explained in Section 4.2.1.

Generation of LexerCode[Suffix].mo

The generation of the file LexerCode[Suffix].mo requires a search in the third

and last section identified in the file lexer.c generated by FLEX. The regular

expression function regex provided by the included file System.mo is used to

match the specified return actions for each final state of the DFA explained

in Section 4.2.1.

The complete file LexerGenerator.mo is available in Appendix B.2 all

together with samples for the files explained here in the sections B.1, E.4

and E.5.

Page 66: OMCCp: A MetaModelica Based Parser Generator Applied to ...

46 CHAPTER 4. IMPLEMENTATION

Considerations in FLEX

The algorithm found in FLEX for the DFA was implemented in MetaMod-

elica with the paradigm model of Functional Programming. This transition

was not straight forward since the file generated by FLEX contains instruc-

tions GOTO; which redirects the control flow of the program to any place in

the code. This behavior was emulated in MetaModelica with the recursion

of the functions.

FLEX generates C code, the arrays in C start the index at the position

0, in MetaModelica the arrays start the index at the position 1. All the

arrays extracted from the file lexer.c were reduced in the first position to

keep equivalent the addressing of arrays inside the DFA.

For the extraction of the required information three main sections were

identified in the code generated by FLEX: the first section includes the

definition of variables and arrays, the second is the DFA and the last one is

the return of the specific token for each action.

4.3.2 Parser Generator

The Parser Generator for OMCCp is implemented in the file ParserGenera-

tor.mo. Similar to the Lexer Generator, the Parser Generator receives as an

input the file parser.c generated by GNU Bison introduced in Section 3.3.

The structure of the file parser.c is more complex than the generated

by FLEX, because it implements a PDA algorithm, instead of the DFA

of the Lexer. However, it keeps some similarity in the structure and the

sections that we previously identified in the file lexer.c. The file parser.c

contains the required information to be used by the file Parser.mo explained

in Section 4.2.2.

Modifications in the grammar file in Bison

The file generated by GNU Bison was insufficient to generate the files re-

quired to parser the grammar and outputs the AST. The grammar file was

modified to include MetaModelica code inside the actions of the grammar

rules to allow the generation of the AST.

The first modification is in the epilogue of the grammar file. The type

definitions for the rules are defined as presented in listing 4.6.

Page 67: OMCCp: A MetaModelica Based Parser Generator Applied to ...

4.3. OPENMODELICA COMPILER-COMPILER PARSER (OMCCP)47

Listing 4.6: Modifications in the Bison Epilogue

1 %{import Absyn ;

3 type R e s t r i c t i o n = Absyn . R e s t r i c t i o n ;

type ClassDef = Absyn . ClassDef ;

5 . . .

%}

The second modification is in the rule description section. The types

inside brackets are introduced after each variable to specify the type. The

parser generator reads these types and uses them to assign the REDUCE

action of each part to the corresponding typed stack from the MultiTyped-

Stack explained above. An example of this is presented in the listing 4.7.

The types Restriction and ClassDef are specified right after each variable

by introducing the tokens [Restriction] and [ClassDef]. The types must be

specified for both, the returning variable and the transformed input.

Listing 4.7: Modifications in the Rules section in Bison

2 %%

. .

4 r e s t r i c t i o n : CLASS { $$ [ R e s t r i c t i o n ] = Absyn . R CLASS( ) ; }| MODEL { $$ [ R e s t r i c t i o n ] = Absyn .R MODEL( ) ; }

6 | RECORD { $$ [ R e s t r i c t i o n ] = Absyn .R RECORD( ) ; }| T PACKAGE { $$ [ R e s t r i c t i o n ] = Absyn .R PACKAGE

( ) ; }8 | TYPE { $$ [ R e s t r i c t i o n ] = Absyn .R TYPE( ) ; }

| FUNCTION { $$ [ R e s t r i c t i o n ] = Absyn .R FUNCTION

( ) ; }10 | UNIONTYPE { $$ [ R e s t r i c t i o n ] = Absyn .

R UNIONTYPE( ) ; }| BLOCK { $$ [ R e s t r i c t i o n ] = Absyn .R BLOCK( ) ; }

12 | CONNECTOR { $$ [ R e s t r i c t i o n ] = Absyn .

R CONNECTOR( ) ; }| EXPANDABLE CONNECTOR { $$ [ R e s t r i c t i o n ] = Absyn

.R EXP CONNECTOR( ) ; }14 | ENUMERATION { $$ [ R e s t r i c t i o n ] = Absyn .

R ENUMERATION( ) ; }| OPERATOR FUNCTION { $$ [ R e s t r i c t i o n ] = Absyn .

R OPERATOR FUNCTION( ) ; }16 | OPERATOR RECORD { $$ [ R e s t r i c t i o n ] = Absyn .

R OPERATOR RECORD( ) ; }| OPERATOR { $$ [ R e s t r i c t i o n ] = Absyn .R OPERATOR( ) ; }

Page 68: OMCCp: A MetaModelica Based Parser Generator Applied to ...

48 CHAPTER 4. IMPLEMENTATION

18

c l a s s d e f : c l a s s p a r t s T END IDENT

20 { $$ [ ClassDef ] = Absyn .PARTS({} , $1 [ C las sPart s

] ,NONE( ) ) ; }| T END IDENT

22 { $$ [ ClassDef ] = Absyn .PARTS({} ,{} ,NONE( ) ) ; }| s t r i n g c l a s s p a r t s T END IDENT

24 { $$ [ ClassDef ] = Absyn .PARTS({} , $2 [ C las sPart s

] ,SOME( $1 ) ) ; }| c l a s sde f enumera t i on { $$ [ ClassDef ] = $1 [

ClassDef ] ; }26 | c l a s s d e f d e r i v e d { $$ [ ClassDef ] = $1 [ ClassDef ] ;

}. . .

28 %%

The keyword (absyntree), visible in the listing 4.7, is used to generate the

final output of the AST. The specification of this keyword in the grammar

rules is mandatory.

Considerations in Bison

GNU Bison does not understand the semantic value of the tokens. The to-

kens received in the list of tokens by the parser contain this semantic value

and can be use to display the error token in the error handling procedure.

But for the error hints that are explained in Section 4.4 a new list struc-

ture was introduced to specify this semantic value. This new list is called

lstSemValue and is shown in listing 4.8. The list order is the same as the

list yytname generated by GNU Bison. This list should be located in the

epilogue of the grammar file, if omitted the error handling mechanism will

display the token names as in the list yytname.

Listing 4.8: List of semantic values of tokens

constant l i s t<String> lstSemValue = {2 ” e r r o r ” , ” undetermined ” , ” read ” , ” wr i t e ” , ”:=” ,

” i f ” , ” then ” , ” e n d i f ” , ” e l s e ” , ” to ” ,

4 ”do” , ”end” , ” whi l e ” , ” ( ” , ” ) ” ,

” I d e n t i t y ” , ” I n t e g e r ” , ”=” , ”<=” , ”<” ,

6 ”>” , ”>=” , ”<>” , ”+” , ”−” ,

”∗” , ”/” , ” ; ” , ”” } ;

Some of the lists generated by GNU Bison make use of the index position

0. Unlike FLEX this arrays were copied verbatim to the ParseTable.mo file,

Page 69: OMCCp: A MetaModelica Based Parser Generator Applied to ...

4.4. ERROR HANDLING 49

and a displacement of 1 was introduce in the algorithm for this arrays in the

PDA implemented in Lexer.mo.

MetaModelica in Bison file

The epilogue and prologue of the grammar file are the places for inserting

custom code. This custom code can be used to implement advance func-

tionalities in the parser such as printing intermediate values or auxiliary

functions for constructing the AST tree.

The complete file ParserGenerator.mo is available in Appendix C.2 all

together with samples for the files explained here in the sections C.1, E.3,

E.1 and E.2.

4.4 Error handling

The error handling implemented in OMCCp is an adaptation of the meth-

ods presented by Burke and Fisher Jr [1982], Bilos [1983] explained in Sec-

tion 2.2.

For implementing these techniques, a backup of the state of the configu-

ration is required to be saved after each shifted token. Four structures were

created to handle the error in OMCCp, two for handling the errors (errors

stack and error state variable), and two more to keep the backup of the

configuration (astStack and state stack).

Primary recovery and error messages techniques were implemented and

will be explained in this section.

4.4.1 Error recovery

In the OMC it is not desirable to use any correction technique for mal-

formed code. This is mainly because the developer may lose the semantic

intentionality in the source code due to an erroneous automatic correction.

This situation happens in when the error recovery merges two tokens in-

stead of inserting the one intended by the developer. Having as an output

a completely different behaviour in the flow of the program.

Despite the considerations above, the parsing tables of GNU Bison pro-

vide a simple error recovery technique. This technique consists in ignoring

Page 70: OMCCp: A MetaModelica Based Parser Generator Applied to ...

50 CHAPTER 4. IMPLEMENTATION

the error token. Following this action, an error flag is activated to detect if

the error can be recovered or not.

This recovery technique works in this way: It uses an integer error flag

and assigns the value of a constant (see maxErrShiftToken in listing 4.9)

when an error is been found. It then decreases the counter each time an

element is shifted. If the flag gets back to zero then the error is being suc-

cessful recovered. If another error is found before the flag gets to zero then

the program stops. The constant maxErrShiftToken can only be modified

in the source code of the file Parser.mo.

Listing 4.9: Constants for error handling

1 /∗ when the e r r o r i s p o s i t i v e the par s e r runs in recovery mode ,

i f the e r r o r i s negat ive , the par s e r runs in t e s t i n g

candidate mode ∗/3 constant Integer maxErrShiftToken = 3 ;

constant Integer maxCandidateTokens = 4 ;

5 constant Integer maxErrRecShift = −5;

OMCCp tries to parse as much as possible with this technique by ignoring

the error token but keeping the errors in an error stack structure that utilizes

later to display the errors and fail the parsing.

The Parser uses an error-flag to determine the error state similar to

BISON but with an extra functionality. If the error state is zero, then no

error is present or has been recovered. When the error is positive the parser

runs in recovery mode and decreases the value after each shifted token.

When it reaches zero, the error has been recovered by ignoring the token. If

the error is negative, the parser runs in testing candidate mode for a specific

error token. This is and important feature for improving the error messages

and will be explained in the next part.

4.4.2 Error messages

OMCCp uses a primary recovery technique to display all possible recovery

candidates to the OpenModelica developer.

When an error is found, the parser fires the errorHandler function in-

cluding the environmental variables that contain the actual configuration of

the parser and the backed up configuration when the last token was shifted.

This backup is used to start an extensive search for the possible valid tokens.

Page 71: OMCCp: A MetaModelica Based Parser Generator Applied to ...

4.4. ERROR HANDLING 51

The input list of tokens is modified according to the type of error that is

going to be tested. The Parser uses a negative constant (see maxErrRecShift

in listing 4.9) that specifies the maxim number of tokens to shift after

accepting a token between the possible candidates. This ensure consistence

with the rest of the input. If a new error is found, then the token is discarded

as a possible candidate, and the Parser continue with the next token in the

list of tokens or the next type of error.

A constant visible in listing 4.9 called maxCandidateTokens constrains

the number of candidates the error message displays. The developer can

sort the tokens in the grammar file to prioritise the most common suggested

tokens and the order it will be displayed to the user. This allows the devel-

oper to understand better the messages and select the correct token more

easy.

As presented in section 2.2.2, we distinguish between 8 types of er-

ror messages for single recovery. In this implementation we use 7 different

kind of error messages for the syntax analysis and one more for the lexical

analysis. The error messages displayed in this implementation are:

• Erase token

• Insert token

• Replace token

• Insert token at the End

• Merge tokens

• Generic error or Undetermined

• Custom error message

For each error type a different test must be run in the Parser. Now we

will explain the conditions required for displaying each kind of message.

Erase token

To test if a token can be erased, we run the Parser modifying the remaining

list of tokens by placing the next token found after the error token as cur-

rent token and ignoring the current token. If the test succeeds we display

Page 72: OMCCp: A MetaModelica Based Parser Generator Applied to ...

52 CHAPTER 4. IMPLEMENTATION

the proper message to the OpenModelica developer suggesting a possible

solution for the error the erasing of the current token.

The error recovery technique explained above allows the parser to keep

running until a next error is found.

Insert token

To test if a token can be inserted before the error token, we run the Parser

modifying the remaining list of tokens by placing the candidate token before

the error token as current token. The candidate token is selected if the test

succeed and placed in the candidate list. All the available tokens are tested.

If there are items in the candidate list we display the proper message to the

OpenModelica developer suggesting as a possible solution for the error the

insertion of one of the tokens present in the candidate list.

Replace token

Similar to the case of Insert Token, we run the Parser modifying the remain-

ing list of tokens by replacing the error token with the candidate token as

current token. The candidate token is selected if the test succeed and placed

in the candidate list. All the available tokens are tested. If there are items

in the candidate list we display the proper message to the OpenModelica

developer. The message suggests as a possible solution for the error the re-

placement of the error token with one of the tokens present in the candidate

list.

Insert token at the End

This case is used only at the end of the program, when no other token is

available in the input of tokens and a non finished acceptance state has been

achieved. All the tokens are tested to verify if they can make the program to

end in a valid acceptance state. If a token succeed then we display the proper

message to the OpenModelica developer suggesting as a possible solution for

the error the insertion of the token found as valid.

Merge tokens

Sometimes a space can be inserted by mistake between two tokens and make

a keyword look to the Parser as two separate identity tokens. In this case

Page 73: OMCCp: A MetaModelica Based Parser Generator Applied to ...

4.4. ERROR HANDLING 53

the error token and the token that follows it are processed again by the

Lexer with their semantic value concatenated. If the Lexer combine them in

a valid token this token is tested to see if it satisfy the test and it is a valid

configuration for the Parser. If it succeeds we display the proper message

to the OpenModelica developer. This message consist in suggesting as a

possible solution the merging of the error token with the next token.

Generic error or Undetermined

It can be possible that no solution or candidate is found for the current

error token. In these cases a generic error message is displayed to the Open-

Modelica developer without any further description of the error than the

location of the token. In this situation the developer needs to fix the error

token without any hint.

Custom error message

Sometimes it is necessary while designing a grammar to communicate to

the developer that a certain transformation rule must not be used in a more

clear language than the presented by the error messages above. For this

reason a custom error message has been introduce. The error message is

introduced in the grammar as presented in listing 4.10. The keyword error

and errorMsg are used to specified that an error has been found. The use

of this custom message will activate the error flag in the parser and starts

the simple error recovery technique explained above.

Listing 4.10: Custom error messages in OMCCp

1 equation : exp EQUALS exp

{ $$ [ Equation ] = Absyn .EQ EQUALS( $1 [ Exp ] , $2 [ Exp ] ) ;

}3 | exp ASSIGN exp

{ e r r o r=true ;

5 errorMsg=” Assignments cannot be used i n s i d e

equat ions ” ; }

A sample of the different type of messages is presented in listing 4.11.

The source code with the errors is also included in the listing 4.12.

Listing 4.11: Error messages in OMCCp

1 ∗∗∗ERROR(S) FOUND∗∗∗

Page 74: OMCCp: A MetaModelica Based Parser Generator Applied to ...

54 CHAPTER 4. IMPLEMENTATION

program .mo : 3 : 1 8 : Syntax ERROR near token : [ T DO ’ do ’ ] , MERGE

tokens [T DO ’ do ’ ] and [ T IDENT ’ ans ’ ] , ERASE token

3 program .mo : 4 : 1 3 : Syntax ERROR near token : [ T ADD ’+’ ] , INSERT

token {T INTCONST or T IDENT} , REPLACE token with {T LPAREN

} , ERASE token

program .mo : 9 : 3 : Syntax ERROR near token : [ T ENDIF ’ e n d i f ’ ] , INSERT

at the End token {T END}5 FAILED PARSING

Listing 4.12: program.mo with errors

1 /∗ PAM program with e r r o r s ∗/read x y z w;

3 while x <> 99 do do

ans := ( x++111) − ( y/3) ;

5 wr i t e ans ;

read x , y ;

7 i f x = 10 then

y := 234 ;

9 e n d i f

As a summary OMCCp implements a non-corrective primary error re-

covery technique. It consists in ignoring the error token and parsing the rest

of the source code if possible. If any error is found, the parsing fails and it

displays a combination of 6 different kind of error messages. These messages

are displayed depending on whether is possible to Erase, Insert, Replace, In-

sert at the End or Merge tokens. When none of these errors are suitable for

recovering the error token, a more generic error for undetermined errors is

displayed.

4.5 Integration OMC

The integration of OMCCp with OMC is done by modifying the file Parser.mo.

This file is located in the folder ‘/trunk/Compiler/FrontEnd/Parser.mo’.

Listing 4.13 shows the original function parse. We can notice in the line

5 an external call to the C function omparse implemented in ANTLR.

Listing 4.13: Parser.mo original function

1 public function parse ” Parse a mo− f i l e ”

input String f i l ename ;

3 output Absyn . Program outProgram ;

Page 75: OMCCp: A MetaModelica Based Parser Generator Applied to ...

4.5. INTEGRATION OMC 55

5 e x t e r n a l ”C” outProgram=Par s e r pa r s e ( f i l ename ) annotat ion (

Library = {”omcruntime” , ”omparse” , ” a n t l r 3 ” }) ;

end parse ;

We modify this function by adding a call to the parser generated by

OMCCp. Listing 4.14 shows the modified function parse that includes the

call to the new parser called ParserModelica.

Listing 4.14: Parser.mo modified function

public function parse ” Parse a mo− f i l e ”

2 input String f i l ename ;

output Absyn . Program outProgram ;

4 l i s t <Types . Token> tokens ;

Boolean r e s u l t ;

6 algorithm

tokens = LexerModel ica . scan ( f i l ename , fa l se ) ;

8 // c a l l the par s e r

( r e s u l t , outProgram ) = ParserModel ica . parse ( tokens , f i l ename ,

fa l se ) ;

10 end parse ;

Page 76: OMCCp: A MetaModelica Based Parser Generator Applied to ...

56 CHAPTER 4. IMPLEMENTATION

Page 77: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Chapter 5

Discussion

In this chapter we will analyse the results and explain the motivation for

the design and the proposed implementation. We start this chapter by

giving details about the OMCCp construction. Then we continue with a

discussion on the OMCCp construction and the compiler OMC. Finally we

address some limitations found during the implementation.

5.1 Analysis of Results

The design presented in Section 4.2 contains two main parts: one is the

generation of the lexer and parser, and the other is the generated files for

the parser.

5.1.1 Lexer and Parser

Lets start talking about the generated files. There are 3 files generated

for the lexer (Lexer.mo, LexTable.mo and LexCode.mo) and four generated

for the parser (Parser.mo, ParseTable.mo, ParseCode.mo and Token.mo)

and one file more for the tokens (Token.mo). This design was chosen with

the aim of achieving functional cohesion and low coupling between the

modules and the functions.

Functional cohesion is a software quality property that is achieved when

the task performed by the parts of each modules are well defined. In the

lexer and the parser we can identify three main parts: the tables, the custom

code and the automata.

57

Page 78: OMCCp: A MetaModelica Based Parser Generator Applied to ...

58 CHAPTER 5. DISCUSSION

The DFA and PDA that are implemented in the files Lexer.mo and

Parser.mo have specific functions that performs well defined tasks. All the

data (parsing tables and lexer tables) is separated from the automata in the

files LexTable.mo and ParseTable.mo. Finally the custom code and specific

actions are located in a different set of files,LexCode.mo and ParseCode.mo.

The low coupling is a software quality property that is achieved when

each module has a low dependency on the other modules and each module

can be easily replaced by another one without major impact on the overall

communication. The two main modules: lexer and parser, are independent

from each other and it can be possible to replace a whole module without

affecting the other as long as the parameters (input and output) in the

interface remains the same.

One possible negative impact of this solution could be the overhead

cause by the function calling and the message passing. Although, we can-

not measure this properly until the whole Modelica grammar is completed

and benchmarks of the current solution against this proposed parser can

be done. Further optimisations can be performed to reduce this possible

negative behaviour.

5.1.2 OMCCp Construction

The generation of the files are performed based on FLEX and GNU Bison.

The main reason for this is the correctness and efficiency of the algorithms

implemented by them. The use of these tools for the generation of the tables

allows OMCCp to reuse the algorithm for implementing the lexer and the

LALR(1) parser. It is known that the generation of these tables is a complex

and error-prone task as presented in Section 2.1.4.

We succeed in implementing the algorithms of FLEX and GNU Bison

in MetaModelica. MetaModelica differs from C in several characteristics.

One of them is that MetaModelica is a functional programming language

and makes use of recursion and loops instead of GOTO instructions. And

the value of the variables are kept in the program by passing them through

input and output parameters instead of the use of global variables as in C.

The steps we went through during the implementation of this project

OMCCp are broadly sketched here:

1. Prototype of a Lexer based on Flex

Page 79: OMCCp: A MetaModelica Based Parser Generator Applied to ...

5.1. ANALYSIS OF RESULTS 59

2. Prototype of a Parser based on BISON

3. Integration of the Lexer and the Parser throught common token spec-

ification.

4. Automatic Generation of the lexer and parser table files for the parser

based on the code generated by Flex and Bison

5. Define the changes required in the grammar definition files to integrate

MetaModelica code in the generated Flex and Bison files.

6. Import the customised code generated by Flex and Bison into the

action resolution file for the lexer and the parser.

7. Implement error handling mechanism and the generation of the can-

didate correction set for the improvement in the error handling.

8. Test the parser with a large subset of Modelica 3.2 + MetaModelica

grammar to find and fix the issues found.

9. Run the Testsuite with the generated parser from the large subset of

Modelica 3.2 + MetaModelica grammar to prove correctness.

The files produced during the implementation of OMCCp are presented

in Table 5.1. The files ending in Modelica.mo are generated from the gram-

mar files. A total of 12340 lines of code were produced during this project.

This gives an idea of the total effort spend during the construction of this

parser.

The software tools used to support this development are presented below:

• Linux Ubuntu (10.10) operative system.

• Eclipse Galileo (3.5.2) with the OpenModelica MTD plugging.

• OpenModelica Compiler OMC always updated according to the latest

source code (1.7.0 - r8600).

• Flex (2.5.35) and Bison (2.4.3) compilers.

• gcc compiler (4.4.5).

• Subversion (1.6.12 - r955767) for version control.

Page 80: OMCCp: A MetaModelica Based Parser Generator Applied to ...

60 CHAPTER 5. DISCUSSION

Table 5.1: OMCCp Files Implementation

FILENAME Lines of CodeLexerGenerator.mo 441LexerCode.tmo 67Lexer.mo 467NewParser.mo 77OMCC.mo 95OMCC.mos 11ParserGenerator.mo 891Parser.mo 896ParseCode.tmo 122Types.mo 194SCRIPT.mos 38lexerModelica.l 207LexerCodeModelica.mo 728LexerModelica.mo 469LexTableModelica.mo 425parserModelica.y 832ParserModelica.mo 898ParseCodeModelica.mo 4515ParseTableModelica.mo 843TokenModelica.mo 124TOTAL 12340

Page 81: OMCCp: A MetaModelica Based Parser Generator Applied to ...

5.1. ANALYSIS OF RESULTS 61

5.1.3 Implementation of a subset of Modelica and Meta-

Modelica grammar

A large subset of Modelica 3.2 and MetaModelica 1.0 grammar was imple-

mented based on the grammar of the Modelica 3.2 specifications [Modelica-

Association, 2010] and MetaModelica specifications [Fritzson and Pop, 2011b].

The subset is large enough to be able to parse all the source code of OM-

CCp. It includes all the class types of Modelica and around 90% of the total

Modelica specification 3.2. In addition, the subset includes the extensions

of MetaModelica used for OMCCp.

The lexer includes 100% of the tokens used by Modelica but without sup-

port for identities inside single quote ’QIdent’ and other characters besides

the common alphabet.

During the implementation of this grammar, some issues were found

and corrected inside the parser. Among these issues we can identify in the

list below some of the changes implemented during the construction of the

grammar.

• Change of recursion for loops for the input of both the lexer and the

parser due to stack overflow errors.

• The reduce of the MultiTyped stack was done in order of the variables

instead of the correct way which was in reverse order to pop the correct

values.

• Added implementation of custom error messages to be inserted in the

parser.

• An additional bug regarding the conversion of large files from chars

into integers were found in the OMC compiler.

The grammar lexerModelica.y and parseModelica.y

The tokens ENDIF, ENDFOR, ENDWHILE, ENDWHEN and ENDCLASS

were added to the lexer grammar to avoid ambiguity in the LALR(1) parser.

Some shift-reductions conflicts were found during the construction of the

grammar. The parser select a shift over reduction in the case this happens.

This allows the longest rules to have priority over the shorter.

We avoided completely reduce-reduce errors. This is a symptom of am-

biguity in the grammar and should always be avoided. The way to avoid

Page 82: OMCCp: A MetaModelica Based Parser Generator Applied to ...

62 CHAPTER 5. DISCUSSION

reduce-reduce errors is by avoiding different rules where the same reduc-

tions can be performed. It happens often when empty transitions are im-

plemented.

The grammar files lexerModelica.y and parseModelica.y are available in

Appendices F.1 and F.2.

Testing the Modelica grammar and performance

We performed a test over the files based on the test suit library implemented

for Modelica. 48 out of 571 test failed. This means that around 92% of the

Modelica grammar was implemented correctly. The rest 8% includes part

of the grammar that were not implemented such as annotations and some

other tokens for prefixes such as FINAL or REPLACEABLE in front of

certain rules.

The test cases that failed are easily identified in the log file. This file

shows the OMCCp error messages as presented in Section 4.4. From here

we can identify and test individual Modelica programs until we add the

required instructions to parse the file, or to correct the construction of the

AST in case the problem is found there.

We discover that the parser was not scaling good for large files and we

performed an optimization over the Lexer and later over the parser. The

optimization consisted in minimize the load of the character list and the

token list used for passing the parameters to the recursive functions inside

the lexer and the parser.

Table 5.2 shows the results in time for all the test cases including the

failed tests for OMCCp and ANTLR. It is important to point that when the

parser fails it performs a search over the candidate tokens that increases the

time of parsing.

Another comparison was performed over the same file as presented in ta-

ble 5.3. This test was performed over the source code of OMCCp. Chart 5.1

shows how the No optimised OMCCp was taking 57 seconds to perform the

parsing over an input of 162.000 chars. After the optimisations we reduce the

total time to 5 seconds. However, we believe that the MultiTyped stack that

consist for the Modelica grammar in around 70 stacks is causing overhead

in the parser.

The computer used for the test has the following configuration:

• CPU: Intel Core DUO T9300

Page 83: OMCCp: A MetaModelica Based Parser Generator Applied to ...

5.1. ANALYSIS OF RESULTS 63

Table 5.2: Test Suite - Compiler

Compiler Time (sec) ResultANTLR 19.367 1 out of 571 tests failedInitial grammar 48 447 out of 568 tests failedIntermedia grammar 58 264 out of 568 tests failedNo Optimization 124.492 98 out of 568 tests failedLexer Optimized 43.294 98 out of 568 tests failedParser Optimized 48.657 48 out of 571 tests failed

Table 5.3: OMCCp - Time Parsing

File Name length No Opt Lexer Opt Parser OptParserGenerator.mo 30955 3.29317966 1.362809223 1.221133662LexerGenerator.mo 15371 1.098076435 0.603257462 0.573149139ParserModelica.mo 31964 3.239946711 1.228217513 1.12769119LexerModelica.mo 15726 1.070857021 0.520705675 0.491600411LexTableModelica.mo 23894 3.163853208 1.940996074 1.708091171LexerCodeModelica.mo 29346 2.904747315 1.305126972 1.177701876ParserModelica.mo 31964 3.136341788 1.220613415 1.127851826ParseCodeModelica.mo 162160 57.240642819 7.805264418 5.45346943ParseTableModelica.mo 57439 12.518531729 4.834436661 3.733743697TokenModelica.mo 4820 0.187905045 0.147879692 0.137828428

0 20000 40000 60000 80000 100000 120000 140000 160000 180000

0

10

20

30

40

50

60

70

OMCC - Time parsing

No OptimizationLexer OptimizedParser Optimized

Characters

Tim

e (

sec)

Figure 5.1: OMCCp - Time Parsing

Page 84: OMCCp: A MetaModelica Based Parser Generator Applied to ...

64 CHAPTER 5. DISCUSSION

• RAM: 4GB

• OS: Ubuntu 10.10

5.2 OpenModelica Compiler

It is expected that OMCCp benefits the development of the OMC by in-

creasing the maintainability of the grammar. This helps a developer to

implement easily modifications in the grammar, due to the familiarity with

tools such as FLEX, GNU Bison and the language MetaModelica.

The new modifications and adaptations can be integrated directly into

the OMC Parser module by modifying the grammar files. However, the

most important benefit of this project is expected to be the OpenModelica

developer that uses the OMC, which will be helped by better hints when

an error is detected by the compiler. The error messages displayed by the

generation of possible candidates help the developer to decide in which way

the program should be corrected.

One additional contribution to the OpenModelica project done during

the development of this project was the discover of few bugs in the OMC

compiler. The bugs reported were corrected by the OMC developers. Those

are related with array operations and sub-string functions. This will increase

the stability of the OMC compiler for its further versions.

The symbol table, used commonly in compiler construction was not de-

veloped in this project because it was not needed by a semantic analyser.

In the further phases of the OMC, a symbol table is built based on the AST

generated by this parser.

5.3 Limitations

Some of the limitations held during the development of this project include:

lack of knowledge in the MetaModelica language, availability of the algo-

rithm and other time limitations that will be addressed here.

MetaModelica is an extension to the Modelica language that is only used

by the OMC developers. One of the first limitations found in this project was

the lack of knowledge to develop the parser in MetaModelica language. A

guide for MetaModelica is today in a draft state and some available exercises

are included. However, it took about a month of reading, prototype trial

Page 85: OMCCp: A MetaModelica Based Parser Generator Applied to ...

5.3. LIMITATIONS 65

and supervision during the implementation of this project to identify the

best practices to use the MetaModelica language in a proper way to build

the parser.

A first basic prototype of a handwritten-lexer was developed to analyse

the benefits and the limitations of this functional programming language.

The knowledge and experience on the development of MetaModelica lan-

guage of the supervisor of this thesis was the key to overcome the difficulties

found due to this lack of expertise and practical source code.

After this initial prototype, FLEX and GNU Bison were defined to be the

base of the parser generator for this project. We found that the algorithm

to create the transition arrays from the grammar files was not available in

FLEX and GNU Bison. Therefore the solution proposed was based on these

applications to calculate the arrays. Later we extract this information from

the generated files in C code. A reverse engineering technique was used

to understand the coded of the generated lexer and parser. Only after we

finished this process, we found the article of Popuri [2006] which clarifies on

how the algorithm of GNU Bison for the parser works. However, this is not

sufficient for the generation of all the tables produced by GNU Bison.

There were also time limitations that made the scope of this project

not big enough for replacing the current parser in ANTLR with the one

generated by OMCCp. The grammar for MetaModelica and Modelica is

only available for the existing parser in the form of LL grammar. The time

for converting the whole set of variables and terminals into LR grammar

was considerable large to include it for this project. A subset large enough

to parse the most of the OMC test suite was implemented to prove the

efficiency and correctness of the algorithm in parsing this grammar.

Page 86: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Chapter 6

Related Work

In this chapter we cover the topic of related work. There are several re-

searches connected with our project that cover both, OpenModelica Com-

piler and the area of compiler construction. We will discuss specially the

latest efforts on bootstrapping and related projects in parser generation.

6.1 OpenModelica Development

Modelica is fundamentally a modelling language, and it is stated by Pop

and Fritzson [2006] that through some small extensions this language can

be used for modelling the domain of programming languages. MetaModel-

ica is created with the intention to accomplish this job. Recent efforts using

MetaModelica in modelling the OMC are presented by Sjolund et al. [2011]

in the Modelica’2011 International Conference. This project is aim to con-

tribute to this process by implementing a parser generator in MetaModelica

that models the parsing behaviour of the OMC. OMCCp is then a piece that

can fit the bootstrapping project.

There are also recent efforts in implementing a Modelica compiler such

as Akesson et al. [2010] that uses JastADD (An aspect-oriented compiler

construction system). However, this efforts differs from the bootstrapping

project referenced above.

The most of the recent projects in OpenModelica are related with the

compiler OMC. Ongoing projects1 such as Java portability, parallel code

1Source: http://www.openmodelica.org/index.php/research/open-master-theses

66

Page 87: OMCCp: A MetaModelica Based Parser Generator Applied to ...

6.2. COMPILER-COMPILER CONSTRUCTION 67

generator and this project of a MetaModelica parser generator are prove of

this.

6.2 Compiler-Compiler Construction

Compiler construction and specially parser generation is still an active re-

search area, even though is based on established knowledge from researches

done several decades ago. Several projects can be found such as “The FIKA

parser generator” by Pise [2010], which also supports LALR(1) grammars

and aims to implement inheritance reuse of grammars unlike the parser

generators we covered in this project (FLEX, BISON and ANTLR).

There are also more efforts specifically in parser generators testing that

can be an important source for further work in this project such as the

research done by Sampath et al. [2007]. This research guides the generation

of tokens for testing lexers generated by FLEX.

Finally in the area of error recovery and messaging there are recent efforts

by de Jonge et al. [2010]. This project aims to implement novel techniques

for improving the accuracy of the current error recovering techniques. These

techniques make use of other characteristics of the source code such as in-

dentation, which is usually placed with the aim of making the code more

human readable.

Page 88: OMCCp: A MetaModelica Based Parser Generator Applied to ...

68 CHAPTER 6. RELATED WORK

Page 89: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Chapter 7

Conclusions

“People think that computer science is the art of geniuses but the

actual reality is the opposite, just many people doing things that

build on each other, like a wall of mini stones.” Donald Knuth

In this last chapter we present the final conclusions of this thesis. We base

the contribution on the implementation and discussion of OMCCp presented

in Chapters 4 and 5. We end this report by addressing some future work

desirable for the continuation of this thesis.

7.1 Accomplishments

We succeed in accomplish the three goals initially presented in section 1.2

for this master’s thesis.

• A Lexer and a Parser for Modelica and MetaModelica grammar that

outputs the Abstract Syntax Tree (AST) for the language processed.

• Lexer and Parser generator written in MetaModelica language.

• Improve in the error handling messages compared with ANTLR; specif-

ically the messages concerning error correction hints of malformed syn-

tax.

From the results presented in Chapter 4 and discussed in Chapter 5, we

can identify the main contribution of this work, which is the implementa-

tion of the OpenModelica Compiler-Compiler parser generator (OMCCp)

69

Page 90: OMCCp: A MetaModelica Based Parser Generator Applied to ...

70 CHAPTER 7. CONCLUSIONS

that can be included in the bootstrapping project of the OpenModelica

Compiler (OMC) as replacement of the ANTLR tool. OMCCp is a parser

generator with low coupling and functional cohesion that allows the genera-

tion of MetaModelica code from the Modelica and MetaModelica grammar

specification.

OMCCp contributes to the OpenModelica developer task by implement-

ing error handling techniques that display understandable error correction

candidates. This feature will benefit directly the OpenModelica developers

by giving them understandable hints to correct the source code.

The implementation of more than 90% of the Modelica 3.2 and Meta-

Modelica grammar is a remarkable advance towards the future replacement

of the ANTLR parser.

From the performed tests we concluded that ANTLR is still faster than

OMCC. The two optimizations performed increased the speed of the parser

by 319.76% in average over the source code of OMCCp and it is 10 times

faster for the larger file we used with 160k characters. We believe there is

still an overhead for handling the large MultiTyped stack for the construction

of the AST. Despite that, the scalability of the parser is linear after the

optimization.

However, the parser should be optimized to handle large files in order to

improve the performance. After this OMCCp can be a good candidate to

replace ANTLR and be included in the bootstrapping project.

Another additional contribution of this work was the discover of some

bugs in the OMC compiler related with array operations and sub-string

functions. The OpenModelica developers fixed these bugs. This contribu-

tion aims to archive a better and stable OMC compiler.

7.2 Future Work

Despite the accomplishments of this thesis, further work is required to

archive other desired goals for the OMC, including the ones enumerated

here:

• Optimization for performance of the algorithm for both the lexer the

parser.

• Complete the full set of the grammar for Modelica 3.2 and MetaMod-

Page 91: OMCCp: A MetaModelica Based Parser Generator Applied to ...

7.2. FUTURE WORK 71

elica and extend it for the coming Modelica 4.

• Implement error recovery mechanism explained in section 2.2.1. The

first and the second method are possible to be implemented here.

• Integrate the parser generated by OMCC as part of the OMC in re-

placement of the current ANTLR as part of the Bootstrapping project

[Sjolund et al., 2011].

• Perform benchmark test to measure the speed in comparison with

ANTLR. This can be more accurate after the whole MetaModelica

and Modelica grammars are completed.

• Update the MetaModelica exercises to directly use OMCCp instead of

external C calls to Flex and Bison.

Page 92: OMCCp: A MetaModelica Based Parser Generator Applied to ...

72 CHAPTER 7. CONCLUSIONS

Page 93: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Bibliography

AA Aaby. Compiler Construction using Flex and Bison. Walla Walla Col-lege, 2003. URL http://citeseerx.ist.psu.edu/viewdoc/download?

doi=10.1.1.108.114&amp;rep=rep1&amp;type=pdf. [Accessed May2011]. 23, 32

A.V. Aho, R. Sethi, and J.D. Ullman. Compilers: principles, techniques,and tools. Addison-Wesley, second edition, 2006. xv, 5, 13, 14, 15, 30

J. Akesson, T Ekman, and G Hedin. Development of a Modelica Com-piler Using JastAdd. Electronic Notes in Theoretical Computer Sci-ence, 203(2):117–131, April 2008. ISSN 15710661. doi: 10.1016/j.entcs.2008.03.048. URL http://linkinghub.elsevier.com/retrieve/pii/

S1571066108001539. [Accessed May 2011]. 18

J. Akesson, Torbjorn Ekman, and Gorel Hedin. Implementation of aModelica compiler using JastAdd attribute grammars. Science of Com-puter Programming, 75(1-2):21–38, January 2010. ISSN 01676423. doi:10.1016/j.scico.2009.07.003. URL http://linkinghub.elsevier.com/

retrieve/pii/S0167642309001087. [Accessed May 2011]. 18, 66

Rober Bilos. Syntactic error diagnosis and recovery. Master’s thesis,Linkoping University, Linkoping, 1983. 16, 49

D. Blasband. Parsing in a hostile world. Proceedings Eighth Working Confer-ence on Reverse Engineering, pages 291–300, 2001. doi: 10.1109/WCRE.2001.957834. URL http://ieeexplore.ieee.org/lpdocs/epic03/

wrapper.htm?arnumber=957834. [Accessed May 2011]. 12

Michael Burke and G.A. Fisher Jr. A practical method for syntactic error di-agnosis and recovery. In Proceedings of the 1982 SIGPLAN symposium onCompiler construction, pages 67–78. ACM, 1982. ISBN 0897910745. URLhttp://portal.acm.org/citation.cfm?id=800230.806981. [AccessedMay 2011]. 16, 49

Michael G. Burke and Gerald a. Fisher. A practical method for LR and LLsyntactic error diagnosis and recovery. ACM Transactions on Program-ming Languages and Systems, 9(2):164–197, March 1987. ISSN 01640925.

73

Page 94: OMCCp: A MetaModelica Based Parser Generator Applied to ...

74 BIBLIOGRAPHY

doi: 10.1145/22719.22720. URL http://portal.acm.org/citation.

cfm?doid=22719.22720. [Accessed May 2011]. 16

Rafael Corchuelo, Jose a. Perez, Antonio Ruiz, and Miguel Toro. Repairingsyntax errors in LR parsers. ACM Transactions on Programming Lan-guages and Systems, 24(6):698–710, November 2002. ISSN 01640925. doi:10.1145/586088.586092. URL http://portal.acm.org/citation.cfm?

doid=586088.586092. [Accessed May 2011]. 16

M. de Jonge, E. Nilsson-Nyman, L. Kats, and Eelco Visser. Natural andflexible error recovery for generated parsers. Software Language Engineer-ing, pages 204–223, 2010. URL http://www.springerlink.com/index/

b0p750768wum5157.pdf. [Accessed May 2011]. 16, 67

Pierpaolo Degano and Corrado Priami. LR techniques for handlingsyntax errors. Computer Languages, 24(2):73–98, 1998. ISSN0096-0551. URL http://linkinghub.elsevier.com/retrieve/pii/

S0096055197000167. [Accessed May 2011]. 16

F.L DeRemer. Practical translators for LR (k) languages. Project Mac, Mas-sachusetts Institute of Technology, 1969. URL http://publications.

csail.mit.edu/lcs/pubs/ps/MIT-LCS-TR-65.ps. [Accessed May 2011].13

Charles Donnelly and Richard Stallman. GNU Bison Manual version 2.4.3,2010. URL http://www.gnu.org/software/bison/manual/bison.pdf.[Accessed May 2011]. 23, 32, 210

Hilding Elmqvist. Modelica - A Unified Object-Oriented Language for Phys-ical Systems Modeling. EUROSIM -Simulation News Europe, (20):p32,1997. 18

Peter Fritzson. Principles of Object-oriented modeling and simulation withModelica 2.1. IEEE Press, 2004. 1, 210

Peter Fritzson and Peter Bunus. Fritzon Modelica A general OO Languagefor continuous and discrete event system modeling and simulation. InSimulation Symposium, 2002. Proceedings. 35th Annual, pages 365 – 380,2002. 18

Peter Fritzson and Adrian Pop. Meta-programming and language mod-eling with metamodelica 1.0. Technical Report 9, Linkoping Univer-sityLinkoping University, PELAB - Programming Environment Labora-tory, The Institute of Technology, 2011a. 4, 18, 152

Peter Fritzson and Adrian Pop. Towards Modelica 4 Meta-Programmingand Language Modeling with MetaModelica 2.0. Number April. 2011b.unpublished work. 4, 18, 61

Page 95: OMCCp: A MetaModelica Based Parser Generator Applied to ...

BIBLIOGRAPHY 75

Peter Fritzson, Adrian Pop, Peter Aronsson, David Akhvlediani, Bern-hard Bachmann, Vasile Baluta, Simon Bjorklen, Mikael Blom, WilliBraun, David Broman, Stefan Brus, Francesco Casella, Filippo Donida,Henrik Eriksson, Anders Fernstrom, Pavel Grozman, Daniel Hedberg,Michael Hanke, Alf Isaksson, Daniel Kanth, Tommi Karhela, JoelKlinghed, Juha Kortelainen, Alexey Lebedev, Magnus Leksell, OliverLenord, Ha kan Lundvall, Eric Meyers, Hannu Niemisto, Kristoffer Nor-ling, Atanas Pavlov, Pavol Privitzer, Per Sahlin, Wladimir Schamai,Gerhard Schmitz, and Klas Sjoholm. OpenModelica System Docu-mentation. Number November. Open Source Modelica Consortium,Linkoping, 2009. URL http://www.ida.liu.se/labs/pelab/modelica/

OpenModelica/releases/1.6.0/doc/OpenModelicaSystem.pdf. [Ac-cessed May 2011]. xiii, 1, 18, 23, 24

Denis Howe. The Free On-line Dictionary of Computing, 2010. URL http:

//foldoc.org/. [Accessed May 2011]. 209, 210

OG Kakde. Algorithms for compiler design. CHARLES RIVER MEDIA,INC., 2002. ISBN 81-7008-100-6. 5, 13

L.C.L. Kats, M. de Jonge, E. Nilsson-Nyman, and E. Visser. Providingrapid feedback in generated modular language environments: adding errorrecovery to scannerless generalized-LR parsing. ACM SIGPLAN Notices,44(10):445–464, 2009. ISSN 0362-1340. URL http://portal.acm.org/

citation.cfm?id=1640089.1640122. [Accessed May 2011]. 16

Donald E Knuth. On the Translation of Languages from Left to Right.Information and Control, 8(6):607–639, 1965. ISSN 00199958. doi: 10.1016/S0019-9958(65)90426-2. URL http://linkinghub.elsevier.com/

retrieve/pii/S0019995865904262. 12

Ha kan Lundvall, Kristian Stava ker, Peter Fritzson, and Christoph Kessler.Automatic parallelization of simulation code for equation-based modelswith software pipelining and measurements on three platforms. ACMSIGARCH Computer Architecture News, 36(5):46–55, June 2009. ISSN0163-5964. doi: 10.1145/1556444.1556451. URL http://portal.acm.

org/citation.cfm?id=1556444.1556451. [Accessed May 2011]. 18

Bruce J. McKenzie, Corey Yeatman, and Lorraine de Vere. Error re-pair in shift-reduce parsers. ACM Transactions on Programming Lan-guages and Systems, 17(4):672–689, July 1995. ISSN 01640925. doi:10.1145/210184.210193. URL http://portal.acm.org/citation.cfm?

doid=210184.210193. [Accessed May 2011]. 16

Ashley J.S Mills. ANTLR Tutorial, 2005. URL http://supportweb.cs.

bham.ac.uk/docs/tutorials/docsystem/build/tutorials/antlr/

antlr.html. [Accessed May 2011]. 25

Page 96: OMCCp: A MetaModelica Based Parser Generator Applied to ...

76 BIBLIOGRAPHY

Modelica-Association. Modelica A R© - A Unified Object-Oriented Languagefor Physical Systems Modeling Language Specification. Interface, 2010.4, 61

Terence Parr. The Definitive ANTLR Reference: Building Domain-SpecificLanguages (Pragmatic Programmers). Pragmatic Bookshelf, 2007. ISBN0978739256. 25

Terence Parr and R W Quong. ANTLR: a predicated-LL(k) parser genera-tor. Software Practice Experience, 25(7):789, 1995. ISSN 00380644. URLhttp://portal.acm.org/citation.cfm?id=213593.213603. [AccessedMay 2011]. 1, 25

Vern Paxson. Flex Manual, 2002. URL http://flex.sourceforge.net/

manual/. [Accessed May 2011]. 28

Michal Pise. The Fika Parser Generator. 2010 10th IEEE Working Confer-ence on Source Code Analysis and Manipulation, pages 99–100, Septem-ber 2010. doi: 10.1109/SCAM.2010.27. URL http://ieeexplore.ieee.

org/lpdocs/epic03/wrapper.htm?arnumber=5601827. [Accessed May2011]. 67

Adrian Pop and Peter Fritzson. Debugging natural semantics specifications.Proceedings of the Sixth sixth international symposium on Automatedanalysis-driven debugging - AADEBUG’05, pages 77–82, 2005. doi: 10.1145/1085130.1085140. URL http://portal.acm.org/citation.cfm?

doid=1085130.1085140. [Accessed May 2011]. 18

Adrian Pop and Peter Fritzson. MetaModelica: A unified equation-basedsemantical and mathematical modeling language. Modular ProgrammingLanguages, pages 211–229, 2006. URL http://www.springerlink.com/

index/a5112k4m34067180.pdf. [Accessed May 2011]. 18, 66, 210

Satya Kiran Popuri. Understanding C parsers generated by GNU Bison. FreeSoftware Foundation, 2006. URL http://www.cs.uic.edu/~spopuri/

cparser.html. [Accessed May 2011]. 30, 32, 41, 65

P. Sampath, AC Rajeev, KC Shashidhar, and S Ramesh. How to test pro-gram generators? A case study using flex. In Software Engineering andFormal Methods, 2007. SEFM 2007. Fifth IEEE International Conferenceon, pages 80–92. IEEE, 2007. doi: 10.1109/SEFM.2007.11. URL http:

//ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=4343926. [Ac-cessed May 2011]. 67

M Sipser. Introduction to the Theory of Computation. Thomson CourseTechnology, second edition, 2005. 8, 10

Martin Sjolund. Bidirectional External Function Interface Between Model-ica/MetaModelica and Java. Master’s thesis, Linkoping University, 2009.18

Page 97: OMCCp: A MetaModelica Based Parser Generator Applied to ...

BIBLIOGRAPHY 77

Martin Sjolund, Peter Fritzson, and Adrian Pop. Bootstrapping a ModelicaCompiler aiming at Modelica 4. In 8th International Modelica Conference(Modelica’2011), Dresden, Germany, 2011. 1, 2, 18, 66, 71

Robert Endre Tarjan and Andrew Chi-Chih Yao. Storing a sparse table.Communications of the ACM, 22(11):606–611, November 1979. ISSN00010782. doi: 10.1145/359168.359175. URL http://portal.acm.org/

citation.cfm?doid=359168.359175. [Accessed May 2011]. 30

P.D. Terry. Compilers and Compiler Generators. Africa, 2000. URL http:

//scifac.ru.ac.za/compilers/. [Accessed May 2011]. 5, 13

Page 98: OMCCp: A MetaModelica Based Parser Generator Applied to ...

78 BIBLIOGRAPHY

Page 99: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Appendices

79

Page 100: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Appendix A

OMC CompilerCommands

This appendix contains the source code developed during this project. Itincludes instructions of how to run the OpenModelica Compiler and samplesof both; input files for the generator of the parser and output files generatedfrom the exercise 10 of the MetaModelica guide.

A.1 Parameters - MetaModelica Parser Gen-erator

A.1.1 Generate compilerName

Used as a sufix for the name of the files input lexer and parser.

A.1.2 Run compilerName, fileName

Run the generated compiler with the given fileName as an input

A.2 OMC Commands

To run the Lexer and Parser generator for the compiler [compilerName] itis required the following:

1. lexer[compilerName].c generated from the grammar lexer[compilerName].lin Flex.

2. parser[compilerName].c generated from the grammar parser[compilerName].yin Bison.

80

Page 101: OMCCp: A MetaModelica Based Parser Generator Applied to ...

A.2. OMC COMMANDS 81

Optionally you can test your grammar by generating the files in FLEX andGNU Bison as described in listing A.1.

Listing A.1: Compile Flex and Bison

\ $ f l e x −t − l l e x e r [ compilerName ] . c > l e x e r [ compilerName ] . c2 \$ bison par s e r [ compilerName ] . y −−output=par se r [ compilerName ] . c

Modify the file OMCC.mos presented in listing A.2 to include the gram-mar languages to generate.

Listing A.2: OMCC.mos

g e t I n s t a l l a t i o n D i r e c t o r y P a t h ( ) ;2 l o a d F i l e ( ”OMCC.mo” ) ;

l o a d F i l e ( ” . . / . . / Compiler / U t i l /RTOpts .mo” ) ;4 l o a d F i l e ( ” . . / . . / Compiler / U t i l / U t i l .mo” ) ;

l o a d F i l e ( ” . . / . . / Compiler / U t i l /System .mo” ) ;6 l o a d F i l e ( ” LexerGenerator .mo” ) ;

l o a d F i l e ( ” ParserGenerator .mo” ) ;8 l o a d F i l e ( ” . . / . . / Compiler /FrontEnd/Absyn .mo” ) ;

OMCC. main ({ ” Modelica ” }) ;10

ge tEr ro rS t r i ng ( ) ;

For running the OMCCp use the command presented in listing A.3.

Listing A.3: OMCCP Command

1 $ omc +g=MetaModelica +d=rml OMCC. mostrue

3 truetrue

5 truetrue

7 true

9 Generating FLEX grammar f i l e l e x e r 1 0 . c . . .Generating BISON grammar f i l e parse r10 . c . . .

11 Reading FLEX grammar f i l e l e x e r 1 0 . c . . .Result : Lexer Bu i l t

13 Reading BISON grammar f i l e par se r10 . cResult : Parser Bu i l t

15 9 F i l e s Generated for the language grammar :10OMCC v0 . 7 ( OpenModelica Compiler− Compiler )

17 Copyright 2011 Open Souce Modelica Consorsium (OSMC)

This command generates the following 9 files:

• lexer[compilerName].c

• parser[compilerName].c

• Lexer[compilerName].mo

• LexTable[compilerName].mo

Page 102: OMCCp: A MetaModelica Based Parser Generator Applied to ...

82 APPENDIX A. OMC COMPILER COMMANDS

• LexCode[compilerName].mo

• Parser[compilerName].mo

• ParseTable[compilerName].mo

• ParseCode[compilerName].mo

• Token[compilerName].mo

Additionally for debugging purposes the debug flag can be activated inthe script SCRIPT.mos presented in the appendix G.1 in the line shown inthe listing A.4.

Listing A.4: SCRIPT.mos debug mode

1 Main . main ({ ” Modelica ” , true }) ; // run grammar 10 with debug on

The output of the file can be send to another file as presented in thelisting A.5. The file result.txt will present the state stacks used for thelexer and parser and also some transformations and variables that can betracked back to the original source code.

Listing A.5: OMCCP debug mode

1 omc +g=MetaModelica +d=rml SCRIPT. mos > r e s u l t . txt

Page 103: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Appendix B

Lexer Generator

B.1 Lexer.mo

Listing B.1: Lexer.mo

1 package Lexer ” Implements the DFA of OMCC”import Types ;

3 import LexTable ;import LexerCode ;

5uniontype LexerTable

7 record LEXER TABLEarray<Integer> accept ;

9 array<Integer> ec ;array<Integer> meta ;

11 array<Integer> base ;array<Integer> de f ;

13 array<Integer> nxt ;array<Integer> chk ;

15 array<Integer> a c c l i s t ;end LEXER TABLE;

17 end LexerTable ;

19 uniontype Envrecord ENV

21 Integer s ta r tS t , cur rSt ;Integer pos , sPos , ePos , l i n e n r ;

23 l i s t<Integer> bu f f ;l i s t<Integer> bkBuf ;

25 l i s t<Integer> s tateSk ;Boolean i sDebugging ;

27 String f i leName ;end ENV;

29 end Env ;

31 function scan ”Scan s t a r t s the l e x i c a l ana l y s i s , load the t a b l e sand consume the program to output the tokens ”

input String f i leName ” input source code f i l e ” ;

83

Page 104: OMCCp: A MetaModelica Based Parser Generator Applied to ...

84 APPENDIX B. LEXER GENERATOR

33 input Boolean debug ” f l a g to a c t i v a t e the debug mode” ;output l i s t<OMCCTypes . Token> tokens ” re turn l i s t o f tokens ” ;

35algorithm

37 // load program( tokens ) := match ( fi leName , debug )

39 locall i s t<OMCCTypes . Token> resTokens ;

41 l i s t<Integer> s t r eamInteger ;case ( , )

43 equations t r eamInteger = loadSourceCode ( f i leName ) ;

45 resTokens = l ex ( fi leName , streamInteger , debug ) ;then ( resTokens ) ;

47 end match ;end scan ;

49function s canSt r ing ”Scan s t a r t s the l e x i c a l ana ly s i s , load the

t a b l e s and consume the program to output the tokens ”51 input String f i l e S o u r c e ” input source code f i l e ” ;

input Boolean debug ” f l a g to a c t i v a t e the debug mode” ;53 output l i s t<OMCCTypes . Token> tokens ” re turn l i s t o f tokens ” ;

55 algorithm// load program

57 ( tokens ) := match ( f i l e S o u r c e , debug )local

59 l i s t<OMCCTypes . Token> resTokens ;l i s t<Integer> s t r eamInteger ;

61 l i s t<String> chars ;case ( , )

63 equationchars = s t r i n g L i s t S t r i n g C h a r ( f i l e S o u r c e ) ;

65 // s t reamInteger = U t i l . l i s tMap ( chars , s t r ingChar Int ) ;s t r eamInteger = l i s t ( s t r ingChar Int ( c ) for c in chars ) ;

67 resTokens = l ex ( ”<Str ingSource>” , s t reamInteger , debug ) ;then ( resTokens ) ;

69 end match ;end s canSt r ing ;

71function loadSourceCode

73 input String f i leName ” input source code f i l e ” ;output l i s t<Integer> program ;

75 algorithm( program ) := match ( f i leName )

77 locall i s t<Integer> s t r eamInteger ;

79 l i s t<String> chars ;case ( ”” )

81 equationprint ( ”Empty FileName” ) ;

83 then ({} ) ;case ( )

85 equationchars = s t r i n g L i s t S t r i n g C h a r (System . r e a d F i l e ( f i leName

) ) ;87 // s t reamInteger = U t i l . l i s tMap ( chars , s t r ingChar Int ) ;

Page 105: OMCCp: A MetaModelica Based Parser Generator Applied to ...

B.1. LEXER.MO 85

s t r eamInteger = l i s t ( s t r ingChar Int ( c ) for c in chars );

89 then ( s t r eamInteger ) ;end match ;

91 end loadSourceCode ;

93 function l e x ”Scan s t a r t s the l e x i c a l ana l y s i s , load the t a b l e sand consume the program to output the tokens ”

input String f i leName ” input source code f i l e ” ;95 input l i s t<Integer> program ” source code as a stream of

I n t e g e r s ” ;input Boolean debug ” f l a g to a c t i v a t e the debug mode” ;

97 output l i s t<OMCCTypes . Token> tokens ” re turn l i s t o f tokens ” ;Integer r , cTok ;

99 l i s t<Integer> cProg ;l i s t<String> chars ;

101 array<Integer> mm accept , mm ec , mm meta , mm base , mm def , mm nxt ,mm chk , mm accl i s t ;

Env env ;103 LexerTable l exTab le s ;

algorithm105 // load ar rays

107 mm accept := l i s t A r r a y ( LexTable . yy accept ) ;mm ec := l i s t A r r a y ( LexTable . yy ec ) ;

109 mm meta := l i s t A r r a y ( LexTable . yy meta ) ;mm base := l i s t A r r a y ( LexTable . yy base ) ;

111 mm def := l i s t A r r a y ( LexTable . yy de f ) ;mm nxt := l i s t A r r a y ( LexTable . yy nxt ) ;

113 mm chk := l i s t A r r a y ( LexTable . yy chk ) ;mm accl i s t := l i s t A r r a y ( LexTable . y y a c c l i s t ) ;

115 l exTab le s := LEXER TABLE( mm accept , mm ec , mm meta , mm base ,mm def , mm nxt , mm chk , mm accl i s t ) ;

117 // I n i t i a l i z e the Env Var iab l e senv := ENV(1 ,1 , 1 , 0 , 1 , 1 ,{} ,{} ,{1} , debug , f i leName ) ;

119 i f ( debug==true ) thenprint ( ”\nLexer ana lyze r LexerCode . . . ” + fi leName + ”\n” ) ;

121 // printAny (”\ nLexer ana lyze r LexerCode . . . ” + fi leName + ”\n”) ;

end i f ;123

tokens := {} ;125 i f ( debug ) then

print ( ”\n TOTAL Chars : ” ) ;127 print ( intString ( l i s t L e n g t h ( program ) ) ) ;

end i f ;129 while ( Util . i sListEmpty ( program )==fa l se ) loop

i f ( debug ) then131 print ( ”\nChars remaining : ” ) ;

print ( intString ( l i s t L e n g t h ( program ) ) ) ;133 end i f ;

cTok : : program := program ;135 cProg := {cTok } ;

( tokens , env , cProg ) := consume ( env , cProg , lexTables , tokens ) ;137 i f ( Util . i sListEmpty ( cProg )==fa l se ) then

cTok : : cProg := cProg ;

Page 106: OMCCp: A MetaModelica Based Parser Generator Applied to ...

86 APPENDIX B. LEXER GENERATOR

139 program := cTok : : program ;end i f ;

141 end while ;tokens := l i s t R e v e r s e ( tokens ) ;

143 end l e x ;

145 function consumeinput Env env ;

147 input l i s t<Integer> program ;input LexerTable l exTab le s ;

149 input l i s t<OMCCTypes . Token> tokens ;output l i s t<OMCCTypes . Token> resToken ;

151 output Env env2 ;output l i s t<Integer> program2 ;

153 array<Integer> mm accept , mm ec , mm meta , mm base , mm def , mm nxt ,mm chk , mm accl i s t ;

Integer mm startSt , mm currSt , mm pos , mm sPos , mm ePos , mm linenr ;155 l i s t<Integer> bu f f e r , bkBuffer , s t a t e s ;

String f i leNm ;157 Integer c , cp , mm finish , baseCond ;

Boolean debug ;159 algorithm

LEXER TABLE( accept=mm accept , ec=mm ec , meta=mm meta , base=mm base ,

161 de f=mm def , nxt=mm nxt , chk=mm chk , a c c l i s t=mm accl i s t ) :=lexTab le s ;

163 ENV( s t a r t S t=mm startSt , cur rSt=mm currSt , pos=mm pos , sPos=mm sPos , ePos=mm ePos ,

l i n e n r=mm linenr , bu f f=bu f f e r , bkBuf=bkBuffer , s ta teSk=s ta t e s ,i sDebugging=debug , f i leName=fi leNm ) := env ;

165mm finish := LexTable . y y f i n i s h ;

167 baseCond := mm base [ mm currSt ] ;i f ( debug==true ) then

169 print ( ”\nPROGRAM:{ ” + p r i n t B u f f e r ( program , ”” ) + ”} ” ) ;print ( ”\nBUFFER:{ ” + p r i n t B u f f e r ( bu f f e r , ”” ) + ”} ” ) ;

171 print ( ”\nBKBUFFER:{ ” + p r i n t B u f f e r ( bkBuffer , ”” ) + ”} ” ) ;print ( ”\nSTATE STACK:{ ” + pr in tStack ( s t a t e s , ”” ) + ”} ” ) ;

173 print ( ” base : ” + intString ( baseCond ) + ” s t : ” + intString (mm currSt )+” ” ) ;

end i f ;175 ( resToken , program2 ) := match ( program , tokens )

local177 Integer c , d , act , val , c2 , curr2 , f cha r ;

l i s t<Integer> r e s t ;179 l i s t<OMCCTypes . Token> lToken ;

String sToken ;181 Boolean emptyToken ;

Option<OMCCTypes . Token> otok ;183 case ( , ) // loop tokens

equation185 cp : : r e s t = program ;

b u f f e r = cp : : b u f f e r ;187

mm pos = mm pos+1;189

Page 107: OMCCp: A MetaModelica Based Parser Generator Applied to ...

B.1. LEXER.MO 87

i f ( cp==10) then191 mm linenr = mm linenr +1;

mm ePos = mm sPos ;193 mm sPos = 0 ;

else195 mm sPos = mm sPos+1;

end i f ;197 i f ( debug==true ) then

print ( ”\n [ Reading : ’ ” + intStr ingChar ( cp ) +” ’ at p : ” +intString (mm pos−1)

199 + ” l i n e : ”+ intString ( mm linenr ) + ” rPos : ” +intString (mm sPos ) +” ] ” ) ;

end i f ;201 c = mm ec [ cp ] ;

203 c2 = c ;curr2 = mm currSt ;

205 i f ( debug==true ) thenprint ( ” eva lS ta t e Before [ c” + intString ( c2 ) + ” , s ”+

intString ( curr2 )+” ] ” ) ;207 end i f ;

( mm currSt , c ) = eva lS ta t e ( lexTables , curr2 , c2 ) ;209 i f ( debug==true ) then

print ( ” After [ c” + intString ( c ) + ” , s ”+ intString (mm currSt )+” ] ” ) ;

211 end i f ;i f ( mm currSt>0) then

213 curr2 = mm base [ mm currSt ] ;// p r i n t (”BASE:”+ i n t S t r i n g ( curr2 ) +”]”) ;

215 mm currSt = mm nxt [ curr2 + c ] ;// p r i n t (”NEXT:”+ i n t S t r i n g ( mm currSt ) +”]”) ;

217 elsemm currSt = mm nxt [ c ] ;

219 end i f ;s t a t e s = mm currSt : : s t a t e s ;

221 // printAny ( s t a t e s ) ;// p r i n t ( ” [ c” + i n t S t r i n g ( c ) + ” , s”+ i n t S t r i n g (

mm currSt ) +”]”) ;223 // p r in t ( ” [B: ” + i n t S t r i n g ( mm base [ mm currSt ] ) +”]”) ;

env2 = ENV( mm startSt , mm currSt , mm pos , mm sPos , mm ePos, mm linenr , bu f f e r , r e s t , s t a t e s , debug , f i leNm ) ;

225 lToken = tokens ;

227baseCond = mm base [ mm currSt ] ;

229 i f ( baseCond==mm finish ) theni f ( debug==true ) then

231 print ( ”\n [RESTORE=” + intString (mm accept [ mm currSt ] ) + ” ] ” ) ;

end i f ;233 ( env2 , act ) = f indRule ( lexTables , env2 ) ;

235

237 ( otok , env2 ) = LexerCode . a c t i on ( act , env2 );

Page 108: OMCCp: A MetaModelica Based Parser Generator Applied to ...

88 APPENDIX B. LEXER GENERATOR

239 // read the envENV( s t a r t S t=mm startSt , cur rSt=mm currSt ,

pos=mm pos , sPos=mm sPos , ePos=mm ePos,

241 l i n e n r=mm linenr , bu f f=bu f f e r , bkBuf=bkBuffer , s ta teSk=s ta t e s ,i sDebugging=debug , f i leName=fi leNm )= env2 ;

243 // r e s t o r e the programprogram2 = bkBuffer ;

245 // r e s t a r t cur r ent s t a t eenv2 = ENV( mm startSt , mm startSt , mm pos ,

mm sPos , mm pos , mm linenr , bu f f e r ,{} ,{mm startSt } , debug , f i leNm ) ;

247 lToken = Util . l i s tConsOpt ion ( otok , tokens) ;

i f ( debug ) then249 print ( ”\n CountTokens : ” + intString (

l i s t L e n g t h ( lToken ) ) ) ;end i f ;

251 elseprogram2 = r e s t ; // consume the

cha rac t e r253 end i f ;

255 then ( lToken , program2 ) ;

257 end match ;

259 end consume ;

261

263 function f indRuleinput LexerTable l exTab le s ;

265 input Env env ;output Env env2 ;

267 output Integer ac t i on ;array<Integer> mm accept , mm ec , mm meta , mm base , mm def , mm nxt ,

mm chk , mm accl i s t ;269 Integer mm startSt , mm currSt , mm pos , mm sPos , mm ePos , mm linenr ;

l i s t<Integer> bu f f e r , bkBuffer , s t a t e s ;271 String f i leNm ;

Integer lp , lp1 , stCmp ;273 Boolean st , debug ;

algorithm275 LEXER TABLE( accept=mm accept , ec=mm ec , meta=mm meta , base=

mm base ,de f=mm def , nxt=mm nxt , chk=mm chk , a c c l i s t=mm accl i s t ) :=

lexTab le s ;277 ENV( s t a r t S t=mm startSt , cur rSt=mm currSt , pos=mm pos , sPos=

mm sPos , ePos=mm ePos ,l i n e n r=mm linenr , bu f f=bu f f e r , bkBuf=bkBuffer , s ta teSk=s ta t e s

, i sDebugging=debug , f i leName=fi leNm ) := env ;279

stCmp : : := s t a t e s ;

Page 109: OMCCp: A MetaModelica Based Parser Generator Applied to ...

B.1. LEXER.MO 89

281 lp := mm accept [ stCmp ] ;

283 // stCmp : : := s t a t e s ;lp1 := mm accept [ stCmp+1] ;

285s t := intGt ( lp , 0 ) and intLt ( lp , lp1 ) ;

287 // p r in t (”STATE: [ ” + i n t S t r i n g ( mm currSt )+ ” pos : ” +i n t S t r i n g (mm pos) + ” ] ” ) ;

// printAny ( s t ) ;289 ( env2 , ac t i on ) := match ( s t a t e s , s t )

local291 Integer act , cp ;

l i s t<Integer> r e s tBu f f , r e s t S t a t e s ;293 case ({} , )

equation295

act = mm accl i s t [ lp ] ;297 print ( ”\nERROR:EMPTY STATE STACK” ) ;

then ( env , act ) ;299 case ( , true )

equation301 stCmp : : = s t a t e s ;

lp = mm accept [ stCmp ] ;303 act = mm accl i s t [ lp ] ;

then ( env , act ) ;305 case ( , fa l se )

equation307

cp : : r e s t B u f f = b u f f e r ;309

bkBuffer = cp : : bkBuffer ;311 mm pos = mm pos − 1 ;

mm sPos = mm sPos −1;313 i f ( cp==10) then

mm sPos = mm ePos ;315 mm linenr = mm linenr−1;

end i f ;317 // bkBuffer = cp : : bkBuffer ;

mm currSt : : r e s t S t a t e s = s t a t e s ;319 // printAny ( r e s t S t a t e s ) ;

// p r i n t (” Restore STATE: [ ” + i n t S t r i n g ( mm currSt )+ ”pos : ” + i n t S t r i n g (mm pos) + ” ] ” ) ;

321 env2 = ENV( mm startSt , mm currSt , mm pos , mm sPos , mm ePos ,mm linenr , r e s tBu f f , bkBuffer , r e s t S t a t e s , debug , f i leNm );

( env2 , act ) = f indRule ( lexTables , env2 ) ;323 then ( env2 , act ) ;

325 end match ;end f indRule ;

327function eva lS ta t e

329 input LexerTable l exTab le s ;input Integer cState ;

331 input Integer c ;output Integer new state ;

333 output Integer new c ;

Page 110: OMCCp: A MetaModelica Based Parser Generator Applied to ...

90 APPENDIX B. LEXER GENERATOR

array<Integer> mm accept , mm ec , mm meta , mm base , mm def , mm nxt ,mm chk , mm accl i s t ;

335 Integer val , val2 , chk ;algorithm

337 LEXER TABLE( accept=mm accept , ec=mm ec , meta=mm meta , base=mm base ,

de f=mm def , nxt=mm nxt , chk=mm chk , a c c l i s t=mm accl i s t ) :=lexTab le s ;

339 chk := mm base [ cState ] ;chk := chk + c ;

341 va l := mm chk [ chk ] ;va l2 := mm base [ cState ] + c ;

343 // p r i n t (”{ va l2=” + i n t S t r i n g ( va l2 ) + ”}\n”) ;( new state , new c ) := match ( cState==val )

345 localInteger s , c2 ;

347 case ( true )then ( cState , c ) ;

349 case ( fa l se )equation

351 cState = mm def [ cState ] ;// p r i n t ( ” [ newS : ” + i n t S t r i n g ( cState ) +”]”) ;

353 // c2 = c ;i f ( cState >= LexTable . y y l i m i t ) then

355 c = mm meta [ c ] ;// p r i n t (”META[ c : ” + i n t S t r i n g ( c ) +”]”) ;

357 end i f ;i f ( cState >0) then

359 ( cState , c ) = eva lS ta t e ( lexTables , cState , c ) ;end i f ;

361 then ( cState , c ) ;end match ;

363end eva lS ta t e ;

365function g e t I n f o

367 input l i s t<Integer> bu f f ;input Integer f rPos ;

369 input Integer f l i n e N r ;input String programName ;

371 output OMCCTypes . In f o i n f o ;Integer mm linenr , mm sPos ;

373 Integer c ;algorithm

375 mm sPos := frPos ;mm linenr := f l i n e N r ;

377 while ( Util . i sListEmpty ( bu f f )==fa l se ) loopc : : bu f f := bu f f ;

379 i f ( c==10) thenmm linenr := mm linenr − 1 ;

381 mm sPos := 0 ;else

383 mm sPos := mm sPos − 1 ;end i f ;

385 end while ;i n f o := OMCCTypes . INFO(programName , false , mm linenr , mm sPos+1,

f l i n eNr , f rPos +1,OMCCTypes . getTimeStamp ( ) ) ;

Page 111: OMCCp: A MetaModelica Based Parser Generator Applied to ...

B.1. LEXER.MO 91

387 /∗ i f ( t rue ) thenp r in t (”\nTOKEN f i l e : ” +programName + ” p(” + i n t S t r i n g (

mm sPos ) + ” :” + i n t S t r i n g ( mm linenr ) + ”)−(” +i n t S t r i n g ( f rPos ) + ” :” + i n t S t r i n g ( f l i n e N r ) + ”) ”) ;

389 end i f ; ∗/end g e t I n f o ;

391function p r i n t B u f f e r

393 input l i s t<Integer> i n L i s t ;input String cBuf f ;

395 output String outL i s t ;l i s t<Integer> i n L i s t 2 ;

397 algorithm( ou tL i s t ) := match ( inL i s t , cBuf f )

399 localInteger c ;

401 String new, tout ;l i s t<Integer> r e s t ;

403 case ({} , )then ( cBuf f ) ;

405 elseequation

407 c : : r e s t = i n L i s t ;new = cBuff + intStr ingChar ( c ) ;

409 ( tout ) = p r i n t B u f f e r ( r e s t ,new) ;then ( tout ) ;

411 end match ;end p r i n t B u f f e r ;

413function pr in tStack

415 input l i s t<Integer> i n L i s t ;input String cBuf f ;

417 output String outL i s t ;l i s t<Integer> i n L i s t 2 ;

419 algorithm( ou tL i s t ) := match ( inL i s t , cBuf f )

421 localInteger c ;

423 String new, tout ;l i s t<Integer> r e s t ;

425 case ({} , )then ( cBuf f ) ;

427 elseequation

429 c : : r e s t = i n L i s t ;new = cBuff + ” | ” + intString ( c ) ;

431 ( tout ) = pr in tStack ( r e s t ,new) ;then ( tout ) ;

433 end match ;end pr in tStack ;

435

437end Lexer ;

Page 112: OMCCp: A MetaModelica Based Parser Generator Applied to ...

92 APPENDIX B. LEXER GENERATOR

B.2 LexerGenerator.mo

Listing B.2: LexerGenerator.mo

package LexerGenerator2 import System ;

/∗4∗/

6 constant Boolean debug = fa l se ;

8 constant String l eyend = ParserGenerator . leyend ;

10 function genLexerinput String f l e x F i l e ;

12 input String grammarFile ;input String outFileName ;

14 output String r e s u l t ;String f lexCode , re , ar1 , r e s t ;

16 Boolean r e sBo l ;l i s t<String> resu l tRegex , resTable , chars ;

18 algorithm//open f l e x f i l e and v a l i d a t e

20 i f ( debug==true ) thenprint ( ”\nGenerating Lexer from ” + f l e x F i l e ) ;

22 end i f ;i f ( outFileName<>”” and st r ingLength ( outFileName )<15) then

24 print ( ”\nReading FLEX grammar f i l e ” + f l e x F i l e +” . . . ” ) ;f l exCode := System . r e a d F i l e ( f l e x F i l e ) ;

26 i f ( debug==true ) thenprint ( ”\nBuild Lex Table . . . ” ) ;

28 end i f ;r e sBo l := bui ldLexTable ( f lexCode , ”LexTable” +

outFileName ) ;30 i f ( debug==true ) then

print ( ”\nBuild Lexer . . . ” ) ;32 end i f ;

r e sBo l := bui ldLexer ( outFileName ) ;34 i f ( debug==true ) then

print ( ”\nBuild LexerCode . . . ” ) ;36 end i f ;

r e sBo l := buildLexerCode ( f lexCode , grammarFile ,outFileName ) ;

38 r e s u l t := ” Lexer Bu i l t ” ;else

40 r e s u l t := ” I n v a l i d language grammar name” ;end i f ;

42 end genLexer ;

44 function readPro logEpi loginput String l exerCode ;

46 input String grammarFileName ;output String l exerCodeInc luded ;

48 String grammarFile , ep i l og , prolog , re , ar1 , astRootType ;Integer numMatches , pos1 , pos2 ;

50 l i s t<String> r e su l tRegex ;

Page 113: OMCCp: A MetaModelica Based Parser Generator Applied to ...

B.2. LEXERGENERATOR.MO 93

algorithm52 i f ( debug==true ) then

print ( ”\nRead ep i l o gue and pro logue ” ) ;54 end i f ;

grammarFile := System . r e a d F i l e ( grammarFileName ) ;56

// f i n d pro logue58

pos1 := System . s t r i ngF ind ( grammarFile , ”%{” ) ;60 pos2 := System . s t r i ngF ind ( grammarFile , ”%}” ) ;

62 ar1 := System . s u b s t r i n g ( grammarFile , pos1 +3,pos2−1) ;l exerCodeInc luded := System . s t r i ngRep la c e ( lexerCode , ”%

pro logue%” , ar1 ) ;64

//66 /∗ ar1 := System . s t r i n g F i n d S t r i n g ( grammarFile , ” AstTree ”) ;

pos1 := System . s t r ingF ind ( ar1 ,”=”) ;68 pos2 := System . s t r ingF ind ( ar1 , ” ; ” ) ;

astRootType := System . s ub s t r i n g ( ar1 , pos1 +2,pos2 ) ;70 astRootType := System . trim ( astRootType , ” ”) ;

parserCodeInc luded := System . s t r i ngRep la c e (parserCodeIncluded ,”% astTree %”,astRootType ) ; ∗/

72// f i n d ep i l ogue

74 re := ”%%” ;ar1 := System . s t r i n g F i n d S t r i n g ( grammarFile , r e ) ;

76 ar1 := System . s u b s t r i n g ( ar1 , 3 , s t r ingLength ( ar1 ) ) ;ar1 := System . s t r i n g F i n d S t r i n g ( ar1 , re ) ;

78 ar1 := System . s u b s t r i n g ( ar1 , 3 , s t r ingLength ( ar1 ) ) ;l exerCodeInc luded := System . s t r i ngRep la c e ( lexerCodeInc luded ,

”%ep i l ogue%” , ar1 ) ;80

82 end readPro logEpi log ;

84 function buildLexerCodeinput String f l exCode ;

86 input String grammarFile ;input String outFileName ;

88 output Boolean bu i ldResu l t ;l i s t<String> resTable ;

90 String lexCode , r e s u l t , r e s t , stTime , cp , caseAction , re ;Integer i , numRules , pos , pos2 , posBegin , posReturn , posKeepBuffer

, posBreak , valBegin ;92 algorithm

lexCode := System . r e a d F i l e ( ”LexerCode . tmo” ) ;94 stTime := leyend + getCurrentTimeStr ( ) ;

r e s u l t := System . s t r i ngRep la c e ( lexCode , ”%LexerCode%” , ”LexerCode” + outFileName ) ;

96 r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%time%” , stTime ) ;r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%Token%” , ”Token” +

outFileName ) ;98 r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%Lexer%” , ” Lexer ” +

outFileName ) ;r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%ParseTable%” , ”

ParseTable ” + outFileName ) ;

Page 114: OMCCp: A MetaModelica Based Parser Generator Applied to ...

94 APPENDIX B. LEXER GENERATOR

100 r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%nameSpan%” , ”255” ) ;

102 r e s u l t := readPro logEpi log ( r e s u l t , grammarFile ) ;

104 caseAct ion := ”” ;resTable := {} ;

106 // p r in t (”\ nFind value . . . ” ) ;numRules := f indValue ( f lexCode , ”YY NUM RULES” ) ;

108 re := ”/∗ beg inning o f ac t i on switch ∗/” ;r e s t := System . s t r i n g F i n d S t r i n g ( f lexCode , re ) ;

110 i f ( debug==true ) thenprint ( ”\nbeginning o f ac t i on switch ” ) ;

112 end i f ;for i in 1 : numRules loop

114 cp := ” case ( ” ;resTable := cp : : resTable ;

116 cp := intString ( i ) ;re sTable := cp : : resTable ;

118 cp := ” ) // ” ;resTable := cp : : resTable ;

120re := ” case ” + intString ( i ) + ” : ” ;

122 r e s t := System . s t r i n g F i n d S t r i n g ( f lexCode , re );

i f ( debug==true ) then124 print ( ”\n” +re ) ;

end i f ;126 re := ”#l i n e ” ;

pos := System . s t r i ngF ind ( r e s t , r e ) ;128 pos2 := System . s t r i ngF ind ( r e s t , ” . l ” ) ;

cp := subs t r i ng2 ( r e s t , pos+1, pos2+3) ;130 resTable := cp : : resTable ;

// posReturn , posKeepBuffer , posBreak132 posReturn := System . s t r i ngF ind ( r e s t , ” re turn

” ) ;posBreak := System . s t r i ngF ind ( r e s t , ”YY BREAK

” ) ;134 posBegin := System . s t r i ngF ind ( r e s t , ”BEGIN” ) ;

posKeepBuffer := System . s t r i ngF ind ( r e s t , ”keepBuf fe r ” ) ;

136 // p r in t (”\n pos : ” + i n t S t r i n g ( pos ) + ” :” + ”pos2 : ” + i n t S t r i n g ( pos2 ) + ” :” + ”posB : ”+ i n t S t r i n g ( posBegin ) ) ;

i f ( posBegin < posBreak and posBegin>=0)then // s t a r t s BEGIN switch s t a r t s t a t e

138 // f i n d tokenpos := System . s t r i ngF ind ( r e s t , ” ( ” ) ;

140 pos2 := System . s t r i ngF ind (r e s t , ” ) ” ) ;

cp := subs t r i ng2 ( r e s t , pos+2,pos2 ) ;

142valBegin := f indValue ( f lexCode , cp ) ;

144 valBegin := 1+2∗valBegin ;i f ( debug==true ) then

146 print ( ”\n BEGIN at ” +intString ( valBegin ) ) ;

Page 115: OMCCp: A MetaModelica Based Parser Generator Applied to ...

B.2. LEXERGENERATOR.MO 95

end i f ;148 cp := ”\n equat ion \n mm startSt =

” + intString ( valBegin ) +” ; ” ;resTable := cp : : resTable ;

150 end i f ;

152 i f ( posKeepBuffer < posBreak andposKeepBuffer>=0) then //

s t a r t s keepbu f f e r switchs t a r t s t a t e// p r i n t keep b u f f e r

154 i f ( debug==true ) thenprint ( ”\n keepbu f f e r ” ) ;

156 end i f ;i f ( posBreak < posBegin ) then

158 cp := ”\n equat ion ” ;resTable := cp : : resTable ;

160 end i f ;cp := ”\n buf f e rRet = l i s t R e v e r s e ( b u f f e r ) ;

” ;162 resTable := cp : : resTable ;

end i f ;164

i f ( posBreak > posReturn ) then166 i f ( posBreak < posBegin and posBreak <

posKeepBuffer ) thencp := ”\n equat ion ” ;

168 resTable := cp : : resTable ;end i f ;

170cp := ”\n act2 = Token” ;

172 resTable := cp : : resTable ;resTable := outFileName : :

resTable ;174 cp := ” . ” ;

resTable := cp : : resTable ;176 // f i n d token

pos2 := System . s t r i ngF ind (r e s t , ” ; ” ) ;

178 cp := subs t r ing2 ( r e s t ,posReturn+8, pos2 ) ;

i f ( debug==true ) then180 print ( ”\nFound token : ” +

cp ) ;end i f ;

182 resTable := cp : : resTable ;cp := ” ;\n tok = OMCCTypes .

TOKEN(tokName [ act2−nameSpan ] , act2 ,bu f f e r , i n f o ) ;\n then (SOME(tok ) ) ;\n ” ;

184 resTable := cp : : resTable ;else

186 // p r i n t (”NONE”) ;cp := ”\n then (NONE( ) ) ;\n” ;

188 resTable := cp : : resTable ;end i f ;

190

Page 116: OMCCp: A MetaModelica Based Parser Generator Applied to ...

96 APPENDIX B. LEXER GENERATOR

192 end for ;r e sTable := l i s t R e v e r s e ( resTable ) ;

194 caseAct ion := s t r i n g C h a r L i s t S t r i n g ( resTable ) ;

196 r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%caseAct ion%” ,caseAct ion ) ;

System . w r i t e F i l e ( ”LexerCode” + outFileName + ” .mo” , r e s u l t ) ;198 bu i ldResu l t := true ;

end buildLexerCode ;200

function f indValue202 input String f l exCode ;

input String v a r i a b l e ;204 output Integer value ;

Integer pos ;206 String r e s t , val , r e ;

algorithm208 re := ” d e f i n e ” + v a r i a b l e ;

r e s t := System . s t r i n g F i n d S t r i n g ( f lexCode , re ) ;210 pos := System . s t r i ngF ind ( r e s t , ”\n” ) ;

va l := subs t r ing2 ( r e s t , s t r ingLength ( re ) +1,pos ) ;212 // p r in t (”\n found value : ” + va l ) ;

va lue := s t r i n g I n t ( va l ) ;214 end f indValue ;

216 function bui ldLexerinput String outFileName ;

218 output Boolean bu i ldResu l t ;String lexCode , r e s u l t , stTime , cp ;

220 algorithmlexCode := System . r e a d F i l e ( ” Lexer .mo” ) ;

222 stTime := leyend + getCurrentTimeStr ( ) ;r e s u l t := System . s t r i ngRep la c e ( lexCode , ”LexTable” , ”LexTable”

+ outFileName ) ;224 r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”LexerCode” , ”LexerCode

” + outFileName ) ;cp := ” package Lexer ” + outFileName + ” // ” + stTime ;

226 r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ” package Lexer ” , cp ) ;r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”end Lexer ; ” , ”end

Lexer ” + outFileName + ” ; ” ) ;228 System . w r i t e F i l e ( ” Lexer ” + outFileName + ” .mo” , r e s u l t ) ;

bu i ldResu l t := true ;230 end bui ldLexer ;

232 function bui ldLexTableinput String f l exCode ;

234 input String outFileName ;output Boolean bu i ldResu l t ;

236 String cp , re , re1 , ar1 , r e s t , r e s u l t , stTime ;Integer numMatches , pos1 , pos2 , l en ;

238 l i s t<String> resu l tRegex , resTable , chars ;

240 algorithm

242 stTime := leyend + getCurrentTimeStr ( ) ;

Page 117: OMCCp: A MetaModelica Based Parser Generator Applied to ...

B.2. LEXERGENERATOR.MO 97

244 cp := ” package ” + outFileName +” // ” + stTime + ” \n\nconstant I n t e g e r y y l i m i t := ” ;

246 resTable := cp : : { } ;

248 // I n s e r t y y l i m i tre := ” i f ( y y c u r r e n t s t a t e >= ” ;

250 re1 := ” i f ( y y c u r r e n t s t a t e >=[ˆ) ] ∗ ) ” ;( numMatches , r e su l tRegex ) := System . regex ( f lexCode , re1 , 1 ,

false , fa l se ) ;252

ar1 : : := resu l tRegex ;254 i f ( debug==true ) then

print ( ”\nFound regex : ” + ar1 ) ;256 end i f ;

numMatches :=0;258 ( numMatches , r e su l tRegex ) := System . regex ( ” i f (

y y c u r r e n t s t a t e >= 65 ) ” , ” [0−9]∗” ,2 , false , fa l se ) ;i f ( debug==true ) then

260 print ( ”\nNumMatches : ” + intString ( numMatches ) ) ;end i f ;

262 cp : : := resu l tRegex ;i f ( debug==true ) then

264 print ( ”\nFound regex2 : ” + cp ) ;end i f ;

266r e s t := System . s t r i n g F i n d S t r i n g ( f lexCode , re ) ;

268pos2 := System . s t r i ngF ind ( r e s t , ” ) ” ) ;

270 ar1 := subs t r ing2 ( r e s t , s t r ingLength ( re ) +1,pos2−1) ;resTable := ar1 : : re sTable ;

272cp := ” ;\n\nconstant I n t e g e r y y f i n i s h := ” ;

274 resTable := cp : : resTable ;re := ” whi l e ( yy base [ y y c u r r e n t s t a t e ] != ” ;

276 r e s t := System . s t r i n g F i n d S t r i n g ( f lexCode , re ) ;pos2 := System . s t r i ngF ind ( r e s t , ” ) ” ) ;

278 ar1 := subs t r ing2 ( r e s t , s t r ingLength ( re ) +1,pos2−1) ;resTable := ar1 : : re sTable ;

280cp := ” ;\n\nconstant l i s t <Integer> y y a c c l i s t := {” ;

282 resTable := cp : : resTable ;

284 // match a c c l i s tre := ” y y a c c l i s t \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;

286 ( numMatches , r e su l tRegex ) := System . regex ( f lexCode , re , 1 , false, fa l se ) ;

ar1 : : := resu l tRegex ;288 i f ( numMatches > 0) then

pos1 := System . s t r i ngF ind ( ar1 , ” , ” ) ;290 pos2 := System . s t r i ngF ind ( ar1 , ”}” ) ;

ar1 := subs t r ing2 ( ar1 , pos1 +2,pos2−1) ;292 else

ar1 := ”” ;294 end i f ;

r e sTable := ar1 : : re sTable ;296

Page 118: OMCCp: A MetaModelica Based Parser Generator Applied to ...

98 APPENDIX B. LEXER GENERATOR

298 cp := ” } ;\n\nconstant l i s t <Integer> yy accept := {” ;resTable := cp : : resTable ;

300 re := ” yy accept \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;( numMatches , r e su l tRegex ) := System . regex ( f lexCode , re , 1 , false

, fa l se ) ;302 r e s t : : := resu l tRegex ;

i f ( numMatches > 0) then304 // r e s t := System . s t r i n g F i n d S t r i n g ( f lexCode , re ) ;

pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;306 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;

ar1 := subs t r ing2 ( r e s t , pos1 +2,pos2−1) ;308 resTable := ar1 : : resTable ;

end i f ;310 cp := ” } ;\n\nconstant l i s t <Integer> yy ec := {” ;

resTable := cp : : resTable ;312 // re := ” s t a t i c yyconst i n t yy ec ” ;

re := ” yy ec \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;314 ( numMatches , r e su l tRegex ) := System . regex ( f lexCode , re , 1 , false

, fa l se ) ;r e s t : : := resu l tRegex ;

316 i f ( numMatches > 0) then// r e s t := System . s t r i n g F i n d S t r i n g ( f lexCode , re ) ;

318 pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;

320 ar1 := subs t r ing2 ( r e s t , pos1 +2,pos2−1) ;resTable := ar1 : : re sTable ;

322 end i f ;cp := ” } ;\n\nconstant l i s t <Integer> yy meta := {” ;

324 resTable := cp : : resTable ;// re := ” s t a t i c yyconst i n t yy meta ” ;

326 re := ”yy meta \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;( numMatches , r e su l tRegex ) := System . regex ( f lexCode , re , 1 , false

, fa l se ) ;328 r e s t : : := resu l tRegex ;

i f ( numMatches > 0) then330 // r e s t := System . s t r i n g F i n d S t r i n g ( f lexCode , re ) ;

pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;332 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;

ar1 := subs t r ing2 ( r e s t , pos1 +2,pos2−1) ;334 resTable := ar1 : : resTable ;

end i f ;336

cp := ” } ;\n\nconstant l i s t <Integer> yy base := {” ;338 resTable := cp : : resTable ;

340 // re := ” s t a t i c yyconst shor t i n t yy base ” ;re := ” yy base \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;

342 ( numMatches , r e su l tRegex ) := System . regex ( f lexCode , re , 1 , false, fa l se ) ;

r e s t : : := resu l tRegex ;344 i f ( numMatches > 0) then

// r e s t := System . s t r i n g F i n d S t r i n g ( f lexCode , re ) ;346 pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;

pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;348 ar1 := subs t r ing2 ( r e s t , pos1 +2,pos2−1) ;

resTable := ar1 : : re sTable ;

Page 119: OMCCp: A MetaModelica Based Parser Generator Applied to ...

B.2. LEXERGENERATOR.MO 99

350 end i f ;

352 cp := ” } ;\n\nconstant l i s t <Integer> yy de f := {” ;resTable := cp : : resTable ;

354 // re := ” s t a t i c yyconst shor t i n t yy de f ” ;re := ” yy de f \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;

356 ( numMatches , r e su l tRegex ) := System . regex ( f lexCode , re , 1 , false, fa l se ) ;

r e s t : : := resu l tRegex ;358 i f ( numMatches > 0) then

// r e s t := System . s t r i n g F i n d S t r i n g ( f lexCode , re ) ;360 pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;

pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;362 ar1 := subs t r ing2 ( r e s t , pos1 +2,pos2−1) ;

resTable := ar1 : : re sTable ;364 end i f ;

366 cp := ” } ;\n\nconstant l i s t <Integer> yy nxt := {” ;resTable := cp : : resTable ;

368 // re := ” s t a t i c yyconst shor t i n t yy nxt ” ;re := ” yy nxt \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;

370 ( numMatches , r e su l tRegex ) := System . regex ( f lexCode , re , 1 , false, fa l se ) ;

r e s t : : := resu l tRegex ;372 i f ( debug==true ) then

print ( ”\nREST next ” + r e s t ) ;374 end i f ;

i f ( numMatches > 0) then376 // r e s t := System . s t r i n g F i n d S t r i n g ( f lexCode , re ) ;

pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;378 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;

ar1 := subs t r ing2 ( r e s t , pos1 +2,pos2−1) ;380 resTable := ar1 : : resTable ;

end i f ;382

cp := ” } ;\n\nconstant l i s t <Integer> yy chk := {” ;384 resTable := cp : : resTable ;

re := ” s t a t i c yyconst shor t i n t yy chk ” ;386 re := ” yy chk \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;

( numMatches , r e su l tRegex ) := System . regex ( f lexCode , re , 1 , false, fa l se ) ;

388 r e s t : : := resu l tRegex ;i f ( numMatches > 0) then

390 // r e s t := System . s t r i n g F i n d S t r i n g ( f lexCode , re ) ;pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;

392 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;ar1 := subs t r ing2 ( r e s t , pos1 +2,pos2−1) ;

394 resTable := ar1 : : resTable ;end i f ;

396

398 cp := ” } ;\n\nend ” + outFileName + ” ; ” ;resTable := cp : : resTable ;

400resTable := l i s t R e v e r s e ( resTable ) ;

402 r e s u l t := s t r i n g C h a r L i s t S t r i n g ( resTable ) ;System . w r i t e F i l e ( outFileName + ” .mo” , r e s u l t ) ;

Page 120: OMCCp: A MetaModelica Based Parser Generator Applied to ...

100 APPENDIX B. LEXER GENERATOR

404 bu i ldResu l t := true ;end bui ldLexTable ;

406public function getCurrentTimeStr ”

408 r e tu rn s cur rent time in format Www Mmm dd hh :mm: s s yyyyus ing the asct ime ( ) func t i on in time . h ( l i b c )

410 ”output String t imeStr ;

412 Integer sec , min , hour , mday , mon , year ;algorithm

414 t imeStr := System . getCurrentTimeStr ( ) ;/∗ ( sec , min , hour , mday , mon , year ) := System .

getCurrentDateTime ( ) ;416 t imeStr := i n t S t r i n g ( year ) + ”/” + i n t S t r i n g (mon)+ ”/” +

i n t S t r i n g (mday)+” ” + i n t S t r i n g ( hour )+ ” :” + i n t S t r i n g (min ) + ” :” +

i n t S t r i n g ( s ec ) ; ∗/418 end getCurrentTimeStr ;

420 public function subs t r i ng2input String i n S t r i n g ;

422 input Integer s t a r t ;input Integer stop ;

424 output String outSt r ing ;l i s t<String> chars , r e s u l t ;

426 String c ;Integer i ;

428 algorithmoutSt r ing := System . s u b s t r i n g ( inSt r ing , s t a r t , stop ) ;

430 /∗ r e s u l t :={} ;chars := s t r i n g L i s t S t r i n g C h a r ( i n S t r i n g ) ;

432 f o r i in 1 : stop loopc : : chars := chars ;

434 i f ( i>=s t a r t ) thenr e s u l t := c : : r e s u l t ;

436 end i f ;end f o r ;

438 r e s u l t := l i s t R e v e r s e ( r e s u l t ) ;outSt r ing := s t r i n g C h a r L i s t S t r i n g ( r e s u l t ) ; ∗/

440 end subs t r i ng2 ;

442 end LexerGenerator ;

B.3 LexerCode.tmo

Listing B.3: LexerCode.tmo

package %LexerCode% // Generated %time%2 /∗

Template f o r Lexer Code4 r e p l a c e keywords :

%LexerCode6 %time

%Token

Page 121: OMCCp: A MetaModelica Based Parser Generator Applied to ...

B.3. LEXERCODE.TMO 101

8 %Lexer%ParseTable

10 %constant%nameSpan

12 %f u n c t i o n s%caseAct ion

14 ∗/import Types ;

16 import %Token%;import %Lexer%;

18 import %ParseTable%;

20 %pro logue%

22 function ac t i oninput Integer act ;

24 input %Lexer%.Env env ;output Option<OMCCTypes . Token> token ;

26 output %Lexer%.Env env2 ;Integer mm startSt , mm currSt , mm pos , mm sPos , mm ePos ,

mm linenr , mm fl inenr ;28 l i s t<Integer> bu f f e r , bkBuffer , tb , bu f f e rRet ;

OMCCTypes . In f o i n f o ;30 array<String> tokName ;

String sToken , f i leNm ;32 Integer nameSpan , act2 ;

Boolean debug ;34 algorithm

%Lexer%.ENV( s t a r t S t=mm startSt , cur rSt=mm currSt , pos=mm pos ,sPos=mm sPos , ePos=mm ePos ,

36 l i n e n r=mm linenr , bu f f=bu f f e r , bkBuf=bkBuffer , i sDebugging=debug , f i leName=fi leNm ) := env ;

b u f f e r := l i s t R e v e r s e ( b u f f e r ) ;38 tb := b u f f e r ;

sToken := %Lexer%. p r i n t B u f f e r ( tb , ”” ) ;40 tokName := l i s t A r r a y (%ParseTable%.yytname ) ;

nameSpan := %nameSpan%;42 tb := b u f f e r ;

// ( tb , mm fl inenr ) := %Lexer%. l ineUpd ( tb , mm fl inenr ) ;44 i n f o := %Lexer%. g e t I n f o ( tb , mm sPos , mm linenr , f i leNm ) ;

// i n f o := OMCCTypes . INFO( fileNm , f a l s e , mm linenr , mm sPos ,mm flinenr , mm pos) ;

46 // p r i n t (”\n” + i n t S t r i n g ( act ) + ” : ” ) ;act2 := act ;

48 bu f f e rRet := {} ;( token ) := matchcontinue ( act )

50 localOMCCTypes . Token tok ;

52 %caseAct ion%case ( )

54 equation// p r i n t ( ” [ ente r e l s e ] ” ) ;

56 print ( ”ERROR TOKEN NOT FOUND: [ ’ ” + sToken + ” ’ TK: ” +intString ( act ) + ” , ” + tokName [ act2 ] + ” ] ” ) ;

tok = OMCCTypes .TOKEN(tokName [ act2 ] , act , bu f f e r , i n f o ) ;58 then (NONE( ) ) ;

end matchcontinue ;

Page 122: OMCCp: A MetaModelica Based Parser Generator Applied to ...

102 APPENDIX B. LEXER GENERATOR

60 env2 := %Lexer%.ENV( mm startSt , mm startSt , mm pos , mm sPos ,mm sPos , mm linenr , buf ferRet , bkBuffer ,{mm startSt } , debug, f i leNm ) ;

i f ( debug==true ) then62 print ( ”\n [TOKEN: ’ ” + sToken + ” ’ ( ”+ intString ( mm linenr )

+ ” : ” + intString (mm sPos ) +” ) id : ” + intString ( act2) + ” ] ” ) ;

end i f ;64 end ac t i on ;

66 %ep i l ogue%

68 end %LexerCode%;

B.4 Types.mo

Listing B.4: Types.mo

package OMCCTypes2 import Absyn ;

import INFO = Absyn . INFO;4

uniontype Token6 record TOKEN

String name ;8 Integer id ;

l i s t<Integer> value ;10 In f o l o c ;

end TOKEN;12

end Token ;14

type In f o = Absyn . In f o ;16

/∗ uniontype In f o18 ”@author adrpo

added 2005−10−29, changed 2006−02−0520 The In f o a t t r i b u t e prov ide s l o c a t i o n in fo rmat ion f o r e lements

and c l a s s e s . ”

22 record INFOStr ing f i leName ” f i leName where the c l a s s i s de f i ned in ” ;

24 Boolean isReadOnly ” isReadOnly : ( t rue | f a l s e ) . Should bet rue f o r l i b r a r i e s ” ;

I n t e g e r l ineNumberStart ” l ineNumberStart ” ;26 I n t e g e r columnNumberStart ”columnNumberStart” ;

I n t e g e r lineNumberEnd ”lineNumberEnd” ;28 I n t e g e r columnNumberEnd ”columnNumberEnd” ;

Absyn . TimeStamp buildTimes ” Build and e d i t t imes ” ;30 end INFO;

32 end In fo ; ∗/

34 function getTimeStamp

Page 123: OMCCp: A MetaModelica Based Parser Generator Applied to ...

B.4. TYPES.MO 103

output Absyn . TimeStamp timeStamp ;36 algorithm

timeStamp := Absyn . dummyTimeStamp ;38 end getTimeStamp ;

40 function printTokeninput Token token ;

42 output String strTk ;String tokName ;

44 Integer idtk , lns , cns , lne , cne ;l i s t<Integer> va l ;

46 In f o i n f o ;algorithm

48 TOKEN(name=tokName , id=idtk , va lue=val , l o c=i n f o ) := token ;INFO( l ineNumberStart=lns , columnNumberStart=cns , lineNumberEnd=

lne , columnNumberEnd=cne ) := i n f o ;50

strTk := ” [TOKEN: ” + tokName + ” ’ ” + p r i n t B u f f e r ( val , ”” ) + ”’ ( ” + intString ( l n s ) + ” : ” + intString ( cns ) + ”−”+intString ( lne ) + ” : ” + intString ( cne ) +” ) ] ” ;

52 end printToken ;

54 function getMergeTokenValueinput Token token1 ;

56 input Token token2 ;output l i s t<Integer> value ;

58 l i s t<Integer> va l1 ;l i s t<Integer> va l2 ;

60 algorithmTOKEN( value=val1 ) := token1 ;

62 TOKEN( value=val2 ) := token2 ;va lue := l i stAppend ( val1 , va l2 ) ;

64 end getMergeTokenValue ;

66 function printErrorTokeninput Token token ;

68 output String strTk ;String tokName , f i leNm ;

70 Integer idtk , lns , cns , lne , cne ;l i s t<Integer> va l ;

72 In f o i n f o ;algorithm

74 TOKEN(name=tokName , id=idtk , va lue=val , l o c=i n f o ) := token ;INFO( f i leName=fileNm , l ineNumberStart=lns , columnNumberStart=cns

, lineNumberEnd=lne , columnNumberEnd=cne ) := i n f o ;76

// strTk := fi leNm + ”:” + i n t S t r i n g ( l n s ) + ” :” + i n t S t r i n g ( cns) + ” : Syntax ERROR near token : [ ” + tokName + ” ’” +p r i n t B u f f e r ( val , ” ” ) + ” ’ ] ” ;

78 // strTk := fi leNm + ”:” + i n t S t r i n g ( l n s ) + ” :” + i n t S t r i n g ( cns) + ” : Syntax ERROR near ’” + p r i n t B u f f e r ( val , ” ” ) + ” ’ ” ;

strTk := ” ’ ” + p r i n t B u f f e r ( val , ”” ) + ” ’ ” ;80 end printErrorToken ;

82 function p r i n t I n f o E r r o rinput In f o i n f o ;

84 output String strTk ;

Page 124: OMCCp: A MetaModelica Based Parser Generator Applied to ...

104 APPENDIX B. LEXER GENERATOR

String tokName , f i leNm ;86 Integer idtk , lns , cns , lne , cne ;

l i s t<Integer> va l ;88 algorithm

INFO( f i leName=fileNm , l ineNumberStart=lns , columnNumberStart=cns, lineNumberEnd=lne , columnNumberEnd=cne ) := i n f o ;

90 // strTk := fi leNm + ”:” + i n t S t r i n g ( l n s ) + ” :” + i n t S t r i n g ( cns) + ” : Syntax ERROR near token : [ ” + tokName + ” ’” +p r i n t B u f f e r ( val , ” ” ) + ” ’ ] ” ;

strTk := fi leNm + ” : ” + intString ( l n s ) + ” : ” + intString ( cns );

92 end p r i n t I n f o E r r o r ;

94 function printShortTokeninput Token token ;

96 output String strTk ;String tokName ;

98 Integer idtk , lns , cns , lne , cne ;l i s t<Integer> va l ;

100 In f o i n f o ;algorithm

102 TOKEN(name=tokName , id=idtk , va lue=val , l o c=i n f o ) := token ;INFO( l ineNumberStart=lns , columnNumberStart=cns , lineNumberEnd=

lne , columnNumberEnd=cne ) := i n f o ;104

// strTk := ” [” + tokName + ” ’” + p r i n t B u f f e r ( val , ” ” ) +” ’ ]” ;106 strTk := ” ’ ” + p r i n t B u f f e r ( val , ”” ) +” ’ ” ;

end printShortToken ;108

function printShortToken2110 input Token token ;

output String strTk ;112 String tokName ;

Integer idtk , lns , cns , lne , cne ;114 l i s t<Integer> va l ;

In f o i n f o ;116 algorithm

TOKEN(name=tokName , id=idtk , va lue=val , l o c=i n f o ) := token ;118 INFO( l ineNumberStart=lns , columnNumberStart=cns , lineNumberEnd=

lne , columnNumberEnd=cne ) := i n f o ;

120 strTk := ” [ ” + tokName + ” ’ ” + p r i n t B u f f e r ( val , ”” ) +” ’ ] ” ;// strTk := ” ’” + p r i n t B u f f e r ( val , ” ” ) +” ’”;

122 end printShortToken2 ;

124 function printTokensinput l i s t<Token> i n L i s t ;

126 input String cBuf f ;output String outL i s t ;

128 l i s t<Token> i n L i s t 2 ;algorithm

130 ( outL i s t ) := match ( inL i s t , cBuf f )local

132 Token c ;String new, tout ;

134 l i s t<Token> r e s t ;case ({} , )

Page 125: OMCCp: A MetaModelica Based Parser Generator Applied to ...

B.4. TYPES.MO 105

136 then ( cBuf f ) ;else

138 equationc : : r e s t = i n L i s t ;

140 //new = cBuf f + printShortToken2 ( c ) ;new = cBuff + printToken ( c ) ;

142 ( tout ) = printTokens ( r e s t ,new) ;then ( tout ) ;

144 end match ;end printTokens ;

146function countTokens

148 input l i s t<Token> i n L i s t ;input Integer sValue ;

150 output Integer outTotal ;l i s t<Token> i n L i s t 2 ;

152 algorithm// printAny (”\ nhere1 ”) ;

154 ( outTotal ) := match ( inL i s t , sValue )local

156 Token c ;Integer new, tout ;

158 l i s t<Token> r e s t ;case ({} , )

160 then ( sValue+1) ;else

162 equation// printAny (”\ nhere2 ”) ;

164 c : : r e s t = i n L i s t ;// printAny (”\ nhere3 ”) ;

166 new = sValue + 1 ;( tout ) = countTokens ( r e s t ,new) ;

168 then ( tout ) ;end match ;

170 // printAny (”\ nhere4 ”) ;end countTokens ;

172function p r i n t B u f f e r

174 input l i s t<Integer> i n L i s t ;input String cBuf f ;

176 output String outL i s t ;l i s t<Integer> i n L i s t 2 ;

178 algorithm( ou tL i s t ) := match ( inL i s t , cBuf f )

180 localInteger c ;

182 String new, tout ;l i s t<Integer> r e s t ;

184 case ({} , )then ( cBuf f ) ;

186 elseequation

188 c : : r e s t = i n L i s t ;new = cBuff + intStr ingChar ( c ) ;

190 ( tout ) = p r i n t B u f f e r ( r e s t ,new) ;then ( tout ) ;

192 end match ;

Page 126: OMCCp: A MetaModelica Based Parser Generator Applied to ...

106 APPENDIX B. LEXER GENERATOR

end p r i n t B u f f e r ;194

end OMCCTypes ;

Page 127: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Appendix C

Parser Generator

C.1 Parser.mo

Listing C.1: Parser.mo

1 package Parserimport Types ;

3 import ParseTable ;import ParseCode ;

5 import Absyn ;import Error ;

7 uniontype Envrecord ENV

9 OMCCTypes . Token crTk , lookAhTk ;l i s t<Integer> s t a t e ;

11 l i s t<String> errMessages ;Integer e r rStatus , sState , cState ;

13 l i s t<OMCCTypes . Token> program , progBk ;ParseCode . AstStack astStack ;

15 Boolean i sDebugging ;l i s t<Integer> stateBackup ;

17 ParseCode . AstStack astStackBackup ;end ENV;

19 end Env ;

21 uniontype ParseDatarecord PARSE TABLE

23 array<Integer> t r a n s l a t e ;array<Integer> prhs ;

25 array<Integer> rhs ;array<Integer> r l i n e ;

27 array<String> tname ;array<Integer> toknum ;

29 array<Integer> r1 ;array<Integer> r2 ;

31 array<Integer> de f a c t ;array<Integer> de fgoto ;

33 array<Integer> pact ;

107

Page 128: OMCCp: A MetaModelica Based Parser Generator Applied to ...

108 APPENDIX C. PARSER GENERATOR

array<Integer> pgoto ;35 array<Integer> t ab l e ;

array<Integer> check ;37 array<Integer> s t o s ; // to be r ep laced

end PARSE TABLE;39 end ParseData ;

41 /∗ when the e r r o r i s p o s i t i v e the par s e r runs in recovery mode ,i f the e r r o r i s negat ive , the par s e r runs in t e s t i n g

candidate mode43 i f the e r r o r i s cero , then no e r r o r i s p re sent or has been

recoveredThe e r r o r va lue de c r ea s e s with each s h i f t e d token ∗/

45 constant Integer maxErrShiftToken = 3 ;constant Integer maxCandidateTokens = 4 ;

47 constant Integer maxErrRecShift = −5;

49 constant Integer ERR TYPE DELETE = 1 ;constant Integer ERR TYPE INSERT = 2 ;

51 constant Integer ERR TYPE REPLACE = 3 ;constant Integer ERR TYPE INSEND = 4 ;

53 constant Integer ERR TYPE MERGE = 5 ;

55 type AstTree = ParseCode . AstTree ;

57 function parse ” r e a l i z e the syntax a n a l y s i s over the l i s t o ftokens and gene ra t e s the AST t r e e ”

input l i s t<OMCCTypes . Token> tokens ” l i s t o f tokens from thel e x e r ” ;

59 input String f i leName ” f i l e name o f the source code ” ;input Boolean debug ” f l a g to output debug messages that

exp la in the s t a t e s o f the machine whi l e par s ing ” ;61 output Boolean r e s u l t ” r e s u l t o f the par s ing ” ;

output ParseCode . AstTree as t ”AST t r e e that i s returned whenthe r e s u l t output i s t rue ” ;

63 array<String> mm tname ;array<Integer> mm translate , mm prhs , mm rhs , mm rline ,

mm toknum , mm r1 , mm r2 , mm defact , mm defgoto ,65 mm pact , mm pgoto , mm table , mm check , mm stos ;

ParseData pt ;67 Env env ;

OMCCTypes . Token emptyTok , cTok , cTok2 ;69 ParseCode . AstStack astStk ;

l i s t<OMCCTypes . Token> rToks ;71 l i s t<Integer> s t a t eS tk ;

l i s t<String> e r rStk ;73 // Boolean r e s u l t ;

algorithm75 i f ( debug ) then

print ( ”\nParsing tokens ParseCode . . . ” + fi leName + ”\n” ) ;77 end i f ;

mm translate := l i s t A r r a y ( ParseTable . y y t r a n s l a t e ) ;79 mm prhs := l i s t A r r a y ( ParseTable . yyprhs ) ;

mm rhs := l i s t A r r a y ( ParseTable . yyrhs ) ;81 mm rline := l i s t A r r a y ( ParseTable . y y r l i n e ) ;

mm tname := l i s t A r r a y ( ParseTable . yytname ) ;83 mm toknum := l i s t A r r a y ( ParseTable . yytoknum ) ;

Page 129: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.1. PARSER.MO 109

mm r1 := l i s t A r r a y ( ParseTable . yyr1 ) ;85 mm r2 := l i s t A r r a y ( ParseTable . yyr2 ) ;

mm defact := l i s t A r r a y ( ParseTable . yyde fact ) ;87 mm defgoto := l i s t A r r a y ( ParseTable . yydefgoto ) ;

mm pact := l i s t A r r a y ( ParseTable . yypact ) ;89 mm pgoto := l i s t A r r a y ( ParseTable . yypgoto ) ;

mm table := l i s t A r r a y ( ParseTable . yytab le ) ;91 mm check := l i s t A r r a y ( ParseTable . yycheck ) ;

mm stos := l i s t A r r a y ( ParseTable . yystos ) ;93

pt := PARSE TABLE( mm translate , mm prhs , mm rhs , mm rline ,mm tname , mm toknum , mm r1 , mm r2

95 , mm defact , mm defgoto , mm pact , mm pgoto , mm table , mm check ,mm stos ) ;

s t a t eS tk := {0} ;97 e r rStk := {} ;

a s tStk := ParseCode . i n i tAs tS tack ( astStk ) ;99 env := ENV(emptyTok , emptyTok , s tateStk , errStk , 0 , 0 , 0 , tokens ,{} ,

astStk , debug , s tateStk , astStk ) ;

101while ( Util . i sListEmpty ( tokens )==fa l se ) loop

103 i f ( debug ) thenprint ( ”\nTokens remaining : ” ) ;

105 print ( intString ( l i s t L e n g t h ( tokens ) ) ) ;end i f ;

107cTok : : tokens := tokens ;

109i f ( Util . i sListEmpty ( tokens )==fa l se ) then

111 cTok2 : : := tokens ;rToks := cTok2 : : { } ;

113 rToks := cTok : : rToks ;else

115 rToks := cTok : : { } ;end i f ;

117 ( rToks , env , r e s u l t , a s t ) := processToken ( rToks , env , pt ) ;i f ( r e s u l t==fa l se ) then

119 break ;end i f ;

121 end while ;

123i f ( debug ) then

125 printAny ( as t ) ;end i f ;

127/∗ i f ( r e s u l t==true ) then

129 p r in t (”\n SUCCEED − (AST) ”) ;e l s e

131 p r in t (”\n FAILED PARSING”) ;end i f ; ∗/

133 end parse ;

135 function addSourceMessageinput l i s t<String> e r rStk ;

137 input OMCCTypes . In f o i n f o ;

Page 130: OMCCp: A MetaModelica Based Parser Generator Applied to ...

110 APPENDIX C. PARSER GENERATOR

algorithm139 Error . addSourceMessage (1 , errStk , i n f o ) ;

// p r i n t ( printSemStack ( l i s t R e v e r s e ( e r rStk ) ,””) ) ;141 end addSourceMessage ;

143 function pr intErrorMessagesinput l i s t<String> e r rStk ;

145 algorithm// p r i n t (”\n ∗∗∗ERROR(S) FOUND∗∗∗ ”) ;

147 // p r in t ( printSemStack ( l i s t R e v e r s e ( e r rStk ) ,””) ) ;end pr intErrorMessages ;

149function processToken

151 input l i s t<OMCCTypes . Token> tokens ;input Env env ;

153 input ParseData pt ;output l i s t<OMCCTypes . Token> rTokens ;

155 output Env env2 ;output Boolean r e s u l t ;

157 output ParseCode . AstTree as t ;l i s t<OMCCTypes . Token> tempTokens ;

159 // parse t a b l e sarray<String> mm tname ;

161 array<Integer> mm translate , mm prhs , mm rhs , mm rline ,mm toknum , mm r1 , mm r2 , mm defact , mm defgoto ,

mm pact , mm pgoto , mm table , mm check , mm stos ;163 // env v a r i a b l e s

OMCCTypes . Token cTok , nTk ;165 ParseCode . AstStack astStk , astSkBk ;

Boolean debug ;167 l i s t<Integer> s tateStk , stateSkBk ;

l i s t<String> e r rStk ;169 String astTmp ;

Integer sSt , cSt , lSt , e r rSt , cFinal , cPactNinf , cTableNinf ;171 l i s t<OMCCTypes . Token> prog , prgBk ;

algorithm173 PARSE TABLE( t r a n s l a t e=mm translate , prhs=mm prhs , rhs=mm rhs ,

r l i n e=mm rline , tname=mm tname , toknum=mm toknum , r1=mm r1 ,r2=mm r2, de f a c t=mm defact , de fgoto=mm defgoto , pact=mm pact , pgoto=

mm pgoto , t a b l e=mm table , check=mm check , s t o s=mm stos ):= pt ;

175ENV( crTk=cTok , lookAhTk=nTk , s t a t e=stateStk , errMessages=errStk ,

e r r S t a t u s=errSt ,177 sSta t e=sSt , cState=cSt , program=prog , progBk=prgBk , astStack=

astStk , isDebugging=debug , stateBackup=stateSkBk ,astStackBackup=astSkBk ) := env ;

i f ( debug ) then179 print ( ”\n [ State : ” + intString ( cSt ) +” ]{ ” + pr in tStack (

s tateStk , ”” ) + ”}\n” ) ;end i f ;

181 env2 := env ;// Star t the LALR(1) Pars ing

183 cF ina l := ParseTable .YYFINAL;cPactNinf := ParseTable .YYPACT NINF;

185 cTableNinf := ParseTable .YYTABLE NINF;

Page 131: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.1. PARSER.MO 111

prog := tokens ;187 // cF ina l==cSt i s a f i n a l s t a t e ? then ACCEPT

// mm pact [ cSt]==cPactNinf i f t h i s REDUCE or ERROR189 r e s u l t := true ;

( rTokens , r e s u l t ) := matchcontinue ( tokens , env , pt , cF ina l==cSt ,mm pact [ cSt+1]==cPactNinf )

191 locall i s t<OMCCTypes . Token> r e s t ;

193 l i s t<Integer> v l ;OMCCTypes . Token c , nt ;

195 Integer n , len , val , tok , tmTok , chkVal ;String nm, semVal ;

197 Absyn . Ident idVal ;case ({} , , , false , fa l se )

199 equationi f ( debug ) then

201 print ( ”\nNow at end o f input :\n” ) ;end i f ;

203 n = mm pact [ cSt +1] ;r e s t = {} ;

205 i f ( debug ) thenprint ( ” [ n : ” + intString (n) + ” ] ” ) ;

207 end i f ;i f (n < 0 or ParseTable .YYLAST < n or mm check [ n+1] <>

0) then209 // goto yyde fau l t ;

n = mm defact [ cSt +1] ;211 i f (n==0) then

// Error Handler213 i f ( debug ) then

print ( ”\n Syntax Error found yyer r l ab5 : ” +intString ( e r rS t ) ) ;

215 // printAny (”\n Syntax Error found yyer r l ab5 : ” +i n t S t r i n g ( e r r S t ) ) ;

end i f ;217 i f ( errSt >=0) then

( env2 , semVal , r e s u l t ) = errorHandle r ( cTok ,env , pt ) ;

219 ENV( crTk=cTok , lookAhTk=nTk ,s t a t e=stateStk , errMessages=errStk , e r r S t a t u s=errSt ,sS ta t e=sSt , cState=cSt ,program=prog , progBk=prgBk ,astStack=astStk , isDebugging=debug , stateBackup=stateSkBk , astStackBackup=astSkBk )= env2 ;

else221 r e s u l t=fa l se ;

end i f ;223 end i f ;

i f ( debug ) then225 print ( ” REDUCE4” ) ;

end i f ;227 env2=reduce (n , env , pt ) ;

ENV( crTk=cTok , lookAhTk=nTk , s t a t e=stateStk ,errMessages=errStk , e r r S t a t u s=errSt , sS ta t e=sSt ,

Page 132: OMCCp: A MetaModelica Based Parser Generator Applied to ...

112 APPENDIX C. PARSER GENERATOR

cState=cSt ,229 program=prog , progBk=prgBk , astStack=astStk ,

isDebugging=debug , stateBackup=stateSkBk ,astStackBackup=astSkBk )= env2 ;

231 elsen = mm table [ n+1] ;

233 i f (n<=0) theni f (n==0 or n==cTableNinf ) then

235 // Error Handleri f ( debug ) then

237 print ( ”\n Syntax Error found yyer r l ab4 : ”+ intString (n) ) ;

end i f ;239 i f ( errSt >=0) then

( env2 , semVal , r e s u l t ) = errorHandle r ( cTok, env , pt ) ;

241 elser e s u l t = fa l se ;

243 end i f ;ENV( crTk=cTok , lookAhTk=nTk ,

s t a t e=stateStk , errMessages=errStk , e r r S t a t u s=errSt ,sS ta t e=sSt , cState=cSt ,program=prog , progBk=prgBk ,astStack=astStk , isDebugging=debug , stateBackup=stateSkBk , astStackBackup=astSkBk )= env2 ;

245 end i f ;n = −n ;

247 i f ( debug ) thenprint ( ” REDUCE5” ) ;

249 end i f ;env2=reduce (n , env , pt ) ;

251 ENV( crTk=cTok , lookAhTk=nTk , s t a t e=stateStk ,errMessages=errStk , e r r S t a t u s=errSt ,sS ta t e=sSt , cState=cSt , program=prog ,progBk=prgBk , astStack=astStk ,isDebugging=debug , stateBackup=stateSkBk, astStackBackup=astSkBk )= env2 ;

253 elsei f ( debug ) then

255 print ( ” SHIFT” ) ;end i f ;

257 i f ( errSt <0) then // reduce the s h i f t e r r o rlookup

i f ( debug ) then259 print ( ”\n∗∗∗−RECOVERY TOKEN INSERTED IS

SHIFTED−∗∗∗” ) ;end i f ;

261 e r rS t = maxErrRecShift ;end i f ;

263 cSt = n ;s ta t eS tk = cSt : : s t a t eS tk ;

Page 133: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.1. PARSER.MO 113

265 env2 = ENV( c , nt , s tateStk , errStk , er rSt , sSt , cSt, r e s t , r e s t , astStk , debug , stateSkBk , astSkBk) ;

267 end i f ;end i f ;

269 i f ( r e s u l t==true and errSt>maxErrRecShift ) then // s topswhen i t f i n d s and e r r o r

i f ( debug ) then271 print ( ”\nReproces ing at the END” ) ;

end i f ;273 ( r e s t , env2 , r e s u l t , a s t ) = processToken ( re s t , env2 , pt ) ;

end i f ;275

then ({} , r e s u l t ) ;277 case ( , , , true , )

equation279 i f ( debug ) then

print ( ”\n\n∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗−ACCEPTED−∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗\n” ) ;

281 end i f ;r e s u l t = true ;

283 i f ( Util . i sListEmpty ( e r rStk )==fa l se ) thenpr intErrorMessages ( e r rStk ) ;

285 r e s u l t = fa l se ;end i f ;

287 as t = ParseCode . getAST ( astStk ) ;then ({} , r e s u l t ) ;

289 case ( , , , false , true )equation

291 n = mm defact [ cSt +1] ;i f (n == 0) then

293 // Error Handleri f ( debug ) then

295 print ( ”\n Syntax Error found yyer r l ab3 : ” +intString (n) ) ;

end i f ;297 i f ( errSt >=0) then

( env2 , semVal , r e s u l t ) = errorHandle r ( cTok, env , pt ) ;

299 ENV( crTk=cTok , lookAhTk=nTk , s t a t e=stateStk , errMessages=errStk ,e r r S t a t u s=errSt , sS ta t e=sSt , cState=cSt , program=prog , progBk=prgBk ,astStack=astStk , isDebugging=debug ,stateBackup=stateSkBk , astStackBackup=astSkBk )= env2 ;

else301 r e s u l t = fa l se ;

end i f ;303 end i f ;

// reduce ;305 i f ( debug ) then

print ( ”REDUCE3” ) ;307 end i f ;

309 env2=reduce (n , env , pt ) ;

Page 134: OMCCp: A MetaModelica Based Parser Generator Applied to ...

114 APPENDIX C. PARSER GENERATOR

311 i f ( r e s u l t==true ) then //s tops when i t f i n d s ande r r o r

( r e s t , env2 , r e s u l t , a s t ) = processToken ( tokens , env2 ,pt ) ;

313 end i f ;

315 then ( r e s t , r e s u l t ) ;case ( , , , false , fa l se )

317 equation/∗ Do appropr ia t e p r o c e s s i n g g iven the cur rent s t a t e .

Read a319 lookahead token i f we need one and don ’ t a l r eady

have one . ∗/c : : r e s t = tokens ;

321 cTok = c ;OMCCTypes .TOKEN( id=tmTok , name=nm, value=v l ) = c ;

323 semVal = p r i n t B u f f e r ( vl , ”” ) ;i f ( debug ) then

325 print ( ” [ ” + nm + ” , ’ ” + semVal +” ’ ] ” ) ;end i f ;

327tok = t r a n s l a t e (tmTok , pt ) ;

329/∗ F i r s t t ry to dec ide what to do without r e f e r e n c e to

lookahead token . ∗/331

n = mm pact [ cSt +1] ;333 i f ( debug ) then

print ( ” [ n : ” + intString (n) + ”−” ) ;335 end i f ;

337 n = n + tok ;i f ( debug ) then

339 print ( ”NT: ” + intString (n) + ” ] ” );

end i f ;341 chkVal = n+1;

i f ( chkVal<=0) then343 chkVal = 1 ;

end i f ;345 i f (n < 0 or ParseTable .YYLAST < n or mm check [ chkVal ]

<> tok ) then// goto yyde fau l t ;

347 n = mm defact [ cSt +1] ;i f (n==0) then

349 // Error Handleri f ( debug ) then

351 print ( ”\n Syntax Error found yyer r l ab2 : ”+ intString (n) ) ;

end i f ;353 i f ( errSt >=0) then

( env2 , semVal , r e s u l t ) = errorHandle r ( cTok, env , pt ) ;

355 ENV( crTk=cTok , lookAhTk=nTk , s t a t e=stateStk , errMessages=errStk ,

Page 135: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.1. PARSER.MO 115

e r r S t a t u s=errSt , sS ta t e=sSt , cState=cSt , program=prog , progBk=prgBk ,astStack=astStk , isDebugging=debug ,stateBackup=stateSkBk , astStackBackup=astSkBk )= env2 ;

else357 e r rS t = maxErrRecShift ;

r e s u l t = fa l se ;359 end i f ;

else361 i f ( debug ) then

print ( ” REDUCE2” ) ;363 end i f ;

env2=reduce (n , env , pt ) ;365 ENV( crTk=cTok , lookAhTk=nTk , s t a t e=stateStk ,

errMessages=errStk , e r r S t a t u s=errSt ,sS ta t e=sSt , cState=cSt , program=prog ,progBk=prgBk , astStack=astStk ,isDebugging=debug , stateBackup=stateSkBk, astStackBackup=astSkBk )= env2 ;

r e s t = tokens ;367 ( r e s t , env2 , r e s u l t , a s t ) = processToken ( r e s t ,

env2 , pt ) ;end i f ;

369 else// try to get the value f o r the ac t i on in the ta b l e

array371 n = mm table [ n+1] ;

i f (n<=0) then373 //

i f (n==0 or n==cTableNinf ) then375 // Error Handler

i f ( debug ) then377 print ( ”\n Syntax Error found

yye r r l ab : ” + intString (n) ) ;end i f ;

379 i f ( errSt >=0) then( env2 , semVal , r e s u l t ) = errorHandle r ( cTok

, env , pt ) ;381 ENV( crTk=cTok , lookAhTk=nTk , s t a t e=

stateStk , errMessages=errStk ,e r r S t a t u s=errSt , sS ta t e=sSt , cState=cSt , program=prog , progBk=prgBk ,astStack=astStk , isDebugging=debug ,stateBackup=stateSkBk , astStackBackup=astSkBk )= env2 ;

else383 r e s u l t = fa l se ;

e r rS t = maxErrRecShift ;385 end i f ;

else387 n = −n ;

i f ( debug ) then389 print ( ” REDUCE” ) ;

end i f ;391 env2=reduce (n , env , pt ) ;

Page 136: OMCCp: A MetaModelica Based Parser Generator Applied to ...

116 APPENDIX C. PARSER GENERATOR

ENV( crTk=cTok , lookAhTk=nTk , s t a t e=stateStk ,errMessages=errStk , e r r S t a t u s=errSt ,sS ta t e=sSt , cState=cSt , program=prog ,progBk=prgBk , astStack=astStk ,isDebugging=debug , stateBackup=stateSkBk, astStackBackup=astSkBk )= env2 ;

393 r e s t = tokens ;( r e s t , env2 , r e s u l t , a s t ) = processToken ( re s t ,

env2 , pt ) ;395 end i f ;

else397 i f ( debug ) then

print ( ” SHIFT1” ) ;399 end i f ;

cSt = n ;401 s ta t eS tk = cSt : : s t a t eS tk ;

idVal = semVal ;403 ( astStk ) = ParseCode . push ( astStk , idVal , cTok ) ;

astSkBk = astStk ;405 stateSkBk = sta t eS tk ;

i f ( errSt <>0) then // reduce the s h i f t e r r o rlookup

407 e r rS t = e r rS t − 1 ;end i f ;

409 env2 = ENV( c , nt , s tateStk , errStk , er rSt , sSt , cSt, r e s t , r e s t , astStk , debug , stateSkBk , astSkBk) ;

end i f ;411 end i f ;

413i f ( errSt<>0 or l i s t L e n g t h ( r e s t )==0) then

415 i f ( ( r e s u l t==true ) and ( errSt>maxErrRecShift ) )then // s tops when i t f i n d s and e r r o r

( r e s t , env2 , r e s u l t , a s t ) = processToken ( re s t ,env2 , pt ) ;

417 end i f ;end i f ;

419 then ( r e s t , r e s u l t ) ;end matchcontinue ;

421 // re turn the AST

423 end processToken ;

425 function er rorHandle rinput OMCCTypes . Token currTok ;

427 input Env env ;input ParseData pt ;

429 output Env env2 ;output String errorMsg ;

431 output Boolean r e s u l t ;// env v a r i a b l e s

433 OMCCTypes . Token cTok , nTk ;ParseCode . AstStack astStk , astSkBk ;

435 Boolean debug ;Integer sSt , cSt , e r rS t ;

437 l i s t<OMCCTypes . Token> prog , prgBk ;

Page 137: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.1. PARSER.MO 117

l i s t<Integer> s tateStk , stateSkBk ;439 l i s t<String> e r rStk ;

// parse t a b l e s441 array<String> mm tname ;

array<Integer> mm translate , mm prhs , mm rhs , mm rline ,mm toknum , mm r1 , mm r2 , mm defact , mm defgoto ,

443 mm pact , mm pgoto , mm table , mm check , mm stos ;

445 l i s t<String> redStk ;Integer numTokens ;

447 String msg , semVal ;

449 algorithmPARSE TABLE( t r a n s l a t e=mm translate , prhs=mm prhs , rhs=mm rhs ,

r l i n e=mm rline , tname=mm tname , toknum=mm toknum , r1=mm r1 ,r2=mm r2

451 , de f a c t=mm defact , de fgoto=mm defgoto , pact=mm pact , pgoto=mm pgoto , t a b l e=mm table , check=mm check , s t o s=mm stos ):= pt ;

453 ENV( crTk=cTok , lookAhTk=nTk , s t a t e=stateStk , sS ta t e=sSt ,errMessages=errStk , e r r S t a t u s=errSt , cState=cSt ,

program=prog , progBk=prgBk , astStack=astStk , isDebugging=debug , stateBackup=stateSkBk , astStackBackup=astSkBk ):= env ;

455i f ( debug ) then

457 print ( ”\nERROR RECOVERY INITIATED : ” ) ;print ( ”\n [ State : ” + intString ( cSt ) +” ]{ ” + pr in tStack

( s tateStk , ”” ) + ”}\n” ) ;459 print ( ”\n [ StateStack Backup :{ ” + pr in tStack ( stateSkBk

, ”” ) + ”}\n” ) ;end i f ;

461 semVal := OMCCTypes . printToken ( currTok ) ;( errorMsg , r e s u l t ) := matchcontinue ( e r rS t ==0,prog )

463 localString erMsg , name ;

465 l i s t<String> cand idate s ;l i s t<OMCCTypes . Token> r e s t ;

467 Integer i , idTok ;OMCCTypes . In f o i n f o ;

469 case ( true ,{} ) // s t a r t e r r o r catch ingequation

471 erMsg = OMCCTypes . pr intErrorToken ( currTok ) ;// i n s e r t token

473 i f ( debug ) thenprint ( ”\n Checking INSERT at the END token : ” ) ;

475 // printAny (”\n Checking INSERT at the END token : ” ) ;end i f ;

477 cand idate s = {} ;cand idate s = checkCandidates ( candidates , env , pt , 3 ) ;

479 i f ( Util . i sListEmpty ( cand idate s )==fa l se ) thenerMsg = erMsg + ” , INSERT at the End token ” +

printCandidateTokens ( candidates , ”” ) ;481 end i f ;

e r rS tk = erMsg : : e r rStk ;483

Page 138: OMCCp: A MetaModelica Based Parser Generator Applied to ...

118 APPENDIX C. PARSER GENERATOR

OMCCTypes .TOKEN( l o c=i n f o ) = currTok ;485 addSourceMessage ( errStk , i n f o ) ;

487 pr intErrorMessages ( e r rStk ) ;e r rS t = maxErrShiftToken ;

489 then ( erMsg , fa l se ) ; //end e r r o r catch ingcase ( true , ) // s t a r t e r r o r catch ing

491 equation

493 //OMCCTypes .TOKEN( id=idTok ) = currTok ;erMsg = OMCCTypes . pr intErrorToken ( currTok ) ;

495i f ( debug ) then

497 print ( ”\n Check MERGE token u n t i l next token ” ) ;end i f ;

499 nTk : : = prog ;OMCCTypes .TOKEN( id=idTok ) = nTk ;

501 i f ( checkToken ( idTok , env , pt , 5 )==true ) then: : nTk : : = prog ;

503 erMsg = erMsg + ” , MERGE tokens ” + OMCCTypes .pr intShortToken ( currTok )

+ ” and ” + OMCCTypes . printShortToken (nTk) ;505 end i f ;

507 // i n s e r t tokeni f ( debug ) then

509 print ( ”\n Checking INSERT token : ” ) ;end i f ;

511 cand idate s = {} ;cand idate s = checkCandidates ( candidates , env , pt , 2 ) ;

513 i f ( Util . i sListEmpty ( cand idate s )==fa l se ) thenerMsg = erMsg + ” , INSERT token ” +

printCandidateTokens ( candidates , ”” ) ;515 // er rStk = erMsg : : e r rStk ;

end i f ;517

e r rS t = maxErrShiftToken ;519

// r e p l a c e token521 // erMsg = ”Syntax Error near ” + semVal ;

i f ( debug ) then523 print ( ”\n Checking REPLACE token : ” ) ;

end i f ;525 cand idate s = {} ;

cand idate s = checkCandidates ( candidates , env , pt , 3 ) ;527 i f ( Util . i sListEmpty ( cand idate s )==fa l se ) then

erMsg = erMsg + ” , REPLACE token with ” +printCandidateTokens ( candidates , ”” ) ;

529 // er rStk = erMsg : : e r rStk ;end i f ;

531e r rS t = maxErrShiftToken ;

533// try to supre s s the token

535 // erMsg = ”Syntax Error near ” + semVal ;i f ( debug ) then

537 print ( ”\n Check ERASE token u n t i l next token ” ) ;

Page 139: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.1. PARSER.MO 119

end i f ;539 nTk : : = prog ;

OMCCTypes .TOKEN( id=idTok ) = nTk ;541 i f ( checkToken ( idTok , env , pt , 1 )==true ) then

erMsg = erMsg + ” , ERASE token ” ;543 // er rStk = erMsg : : e r rStk ;

end i f ;545 // printAny ( e r rStk ) ;

i f ( Util . i sListEmpty ( e r rStk )==true ) then547 e r rStk = erMsg : : { } ;

else549 er rStk = erMsg : : e r rStk ;

end i f ;551 OMCCTypes .TOKEN( l o c=i n f o ) = currTok ;

addSourceMessage ( errStk , i n f o ) ;553 e r r S t = maxErrShiftToken ;

then ( erMsg , true ) ; //end e r r o r catch ing555 case ( false , ) // add one more e r r o r

equation557 pr intErrorMessages ( e r rStk ) ;

erMsg = OMCCTypes . pr intErrorToken ( currTok ) ;559 then ( erMsg , fa l se ) ;

end matchcontinue ;561 i f ( debug==true ) then

print ( ”\nERROR NUM: ” + intString ( e r rS t ) +” DETECTED:\n” +errorMsg ) ;

563 end i f ;env2 := ENV( cTok , nTk , s tateStk , errStk , er rSt , sSt , cSt , prog , prgBk ,

astStk , debug , stateSkBk , astSkBk ) ;565 // env2 := env ;

end er rorHandle r ;567

function checkCandidates569 input l i s t<String> cand idate s ;

input Env env ;571 input ParseData pt ;

input Integer ac t i on ;573 output l i s t<String> resCandidates ;

Integer n ;575 // env v a r i a b l e s

OMCCTypes . Token cTok , nTk ;577 ParseCode . AstStack astStk , astSkBk ;

Boolean debug ;579 Integer sSt , cSt , e r r S t ;

l i s t<OMCCTypes . Token> prog , prgBk ;581 l i s t<Integer> s tateStk , stateSkBk ;

l i s t<String> e r rStk ;583 // parse t a b l e s

array<String> mm tname ;585 array<Integer> mm translate , mm prhs , mm rhs , mm rline ,

mm toknum , mm r1 , mm r2 , mm defact , mm defgoto ,mm pact , mm pgoto , mm table , mm check , mm stos ;

587Integer numTokens , i , j =1;

589 String name , tokVal ;algorithm

591 PARSE TABLE( tname=mm tname) := pt ;

Page 140: OMCCp: A MetaModelica Based Parser Generator Applied to ...

120 APPENDIX C. PARSER GENERATOR

593 resCandidates := cand idates ;numTokens := 255 + ParseTable .YYNTOKENS − 1 ;

595 // exhaust ive search over the tokensfor i in 258 : numTokens loop

597 i f ( checkToken ( i , env , pt , a c t i on )==true ) then//name := mm tname [ i −255] ;

599 i f ( j<=maxCandidateTokens ) thentokVal := getTokenSemValue ( i −255 , pt ) ;

601 resCandidates := tokVal : : r e sCandidates ;j := j +1;

603 elsei := numTokens+1;

605 end i f ;end i f ;

607 end for ;end checkCandidates ;

609function checkToken

611 input Integer chkTok ;input Env env ;

613 input ParseData pt ;input Integer ac t i on ; // 1 d e l e t e 2 i n s e r t 3 r e p l a c e

615 output Boolean r e s u l t ;Integer n ;

617 // env v a r i a b l e sOMCCTypes . Token cTok , nTk ;

619 ParseCode . AstStack astStk , astSkBk ;Boolean debug ;

621 Integer sSt , cSt , e r rS t ;l i s t<OMCCTypes . Token> prog , prgBk ;

623 l i s t<Integer> s tateStk , stateSkBk ;l i s t<String> e r rStk ;

625 // parse t a b l e sarray<String> mm tname ;

627 array<Integer> mm translate , mm prhs , mm rhs , mm rline ,mm toknum , mm r1 , mm r2 , mm defact , mm defgoto ,

mm pact , mm pgoto , mm table , mm check , mm stos ;629 Integer chk2 ;

Env env2 ;631 OMCCTypes . In f o i n f o ;

OMCCTypes . Token candTok ;633 algorithm

PARSE TABLE( t r a n s l a t e=mm translate , prhs=mm prhs , rhs=mm rhs ,r l i n e=mm rline , tname=mm tname , toknum=mm toknum , r1=mm r1 ,r2=mm r2

635 , de f a c t=mm defact , de fgoto=mm defgoto , pact=mm pact , pgoto=mm pgoto , t a b l e=mm table , check=mm check , s t o s=mm stos ):= pt ;

637 ENV( crTk=cTok , lookAhTk=nTk , s t a t e=stateStk , sS ta t e=sSt ,errMessages=errStk , e r r S t a t u s=errSt , cState=cSt , program=prog ,

progBk=prgBk , astStack=astStk , isDebugging=debug ,stateBackup=stateSkBk , astStackBackup=astSkBk ) := env;

639

Page 141: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.1. PARSER.MO 121

i f ( debug ) then641 print ( ”\n ∗∗∗∗ Checking TOKEN: ” + intString ( chkTok ) + ”

ac t i on : ” + intString ( ac t i on ) ) ;// printAny (”\n ∗∗∗∗ Checking TOKEN: ” + i n t S t r i n g ( chkTok )

+ ” ac t i on : ” + i n t S t r i n g ( ac t i on ) ) ;643 end i f ;

// r e s t o r e back up c o n f i g u r a t i o n and run the machine again tocheck candidate

645 i f ( Util . i sListEmpty ( prog )==fa l se ) thencTok : : prog := prog ;

647 i f ( debug ) thenprint ( ”\n ∗∗∗∗ Last token : ” + OMCCTypes .

printToken ( cTok ) ) ;649 end i f ;

i n f o := OMCCTypes . INFO( ”” , false , 1 , 1 , 1 , 1 ,OMCCTypes .getTimeStamp ( ) ) ; // fake p o s i t i o n

651 candTok := OMCCTypes .TOKEN(mm tname [ chkTok−255] ,chkTok ,{65} , i n f o ) ;

else653 i f ( debug ) then

print ( ”\n Creat ing Fake Token p o s i t i o n ” ) ;655 end i f ;

i n f o := OMCCTypes . INFO( ”” , false , 1 , 1 , 1 , 1 ,OMCCTypes .getTimeStamp ( ) ) ; // fake p o s i t i o n

657 candTok := OMCCTypes .TOKEN(mm tname [ chkTok−255] , chkTok,{65} , i n f o ) ;

end i f ;659

i f ( debug ) then661 print ( ”\n ∗∗∗∗ Process candidate token : ” + OMCCTypes .

printToken ( candTok ) + ” ac t i on : ” + intString ( ac t i on ) );

end i f ;663

( prog ) := matchcontinue ( ac t i on )665 local

l i s t<Integer> value ;667 l i s t<OMCCTypes . Token> l s tTokens ;

case (5 ) // Merge669 equation

i f ( Util . i sListEmpty ( prog )==fa l se ) then671 candTok : : prog = prog ;

va lue = OMCCTypes . getMergeTokenValue ( cTok , candTok ) ;673 l s tTokens = Lexer . l e x ( ” f i leName ” , value , debug ) ;

candTok : : = ls tTokens ;675 prog = candTok : : prog ;

end i f ;677 then ( prog ) ;

case (2 ) // I n s e r t679 equation

prog = candTok : : cTok : : prog ;681 then ( prog ) ;

case (3 ) // r e p l a c e683 equation

prog = candTok : : prog ;685 then ( prog ) ;

else then ( prog ) ;

Page 142: OMCCp: A MetaModelica Based Parser Generator Applied to ...

122 APPENDIX C. PARSER GENERATOR

687 end matchcontinue ;

689 cSt : : := stateSkBk ;e r rStk := {} ; // r e s e t e r r o r s

691 e r rS t := −1; // no e r r o r s r e s e t// backup the env v a r i a b l e s to the l a s t s h i f t e d token

693 env2 := ENV( cTok , nTk , stateSkBk , errStk , er rSt , sSt , cSt , prog ,prgBk , astSkBk , debug , stateSkBk , astSkBk ) ;

695 // printAny ( env2 ) ;

697 r e s u l t := fa l se ;i f ( debug ) then

699 // p r in t (”\n\n∗∗∗∗∗ProcessTOKENS : ” + OMCCTypes . pr intTokens (prog , ” ” ) + ” check ” + i n t S t r i n g ( chkTok ) ) ;

end i f ;701 // p r i n t (”\n [ State=”+ i n t S t r i n g ( cSt ) + ” Stack Backup :{” +

pr in tStack ( stateSkBk , ” ” ) + ”} ]\n”) ;// p r i n t (”\n [ StateStack Backup :{” + pr in tStack ( stateSkBk , ” ” ) +

”}\n”) ;703

( , , r e s u l t , ) := processToken ( prog , env2 , pt ) ;705

i f ( r e s u l t and debug ) then707 print ( ”\n ∗∗∗∗ Candidate TOKEN ADDED: ” + intString ( chkTok

) ) ;end i f ;

709 end checkToken ;

711 function reduceinput Integer r u l e ;

713 input Env env ;input ParseData pt ;

715 output Env env2 ;// parse t a b l e s

717 array<String> mm tname ;array<Integer> mm translate , mm prhs , mm rhs , mm rline ,

mm toknum , mm r1 , mm r2 , mm defact , mm defgoto ,719 mm pact , mm pgoto , mm table , mm check , mm stos ;

// env v a r i a b l e s721 OMCCTypes . Token cTok , nTk ;

ParseCode . AstStack astStk ;723 ParseCode . AstStack astSkBk ;

Boolean debug , e r r o r ;725 l i s t<Integer> s tateStk , stateSkBk ;

l i s t<String> errStk , redStk ;727 String astTmp , semVal , errMsg ;

Integer errSt , sSt , cSt ;729 l i s t<OMCCTypes . Token> prog , prgBk ;

Integer i , len , val , n , nSt , chkVal ;731 algorithm

PARSE TABLE( t r a n s l a t e=mm translate , prhs=mm prhs , rhs=mm rhs ,r l i n e=mm rline , tname=mm tname , toknum=mm toknum , r1=mm r1 ,r2=mm r2

733 , de f a c t=mm defact , de fgoto=mm defgoto , pact=mm pact , pgoto=mm pgoto , t a b l e=mm table , check=mm check , s t o s=mm stos ):= pt ;

Page 143: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.1. PARSER.MO 123

735 ENV( crTk=cTok , lookAhTk=nTk , s t a t e=stateStk , sS ta t e=sSt ,errMessages=errStk , e r r S t a t u s=errSt , cState=cSt , program=prog , progBk=prgBk , astStack=astStk ,

isDebugging=debug , stateBackup=stateSkBk , astStackBackup=astSkBk ) := env ;

737 i f r u l e > 0 thenl en := mm r2 [ r u l e ] ;

739 i f ( debug ) thenprint ( ” [ Reducing ( l : ” + intString ( l en ) + ” ,

r : ” + intString ( r u l e ) +” ) ] ” ) ;741 end i f ;

redStk := {} ;743 for i in 1 : l en loop

va l : : s t a t eS tk := s ta t eS tk ;745 end for ;

i f ( errSt >=0) then747 ( astStk , e r ro r , errMsg ) := ParseCode . actionRed

( ru le , astStk , mm r2) ;end i f ;

749 i f ( e r r o r ) thene r rStk := errMsg : : e r rStk ;

751 e r rS t := maxErrShiftToken ;end i f ;

753cSt : : := s ta t eS tk ;

755n := mm r1 [ r u l e ] ;

757nSt := mm pgoto [ n − ParseTable .YYNTOKENS +

1 ] ;759 nSt := nSt + cSt ;

chkVal := nSt +1;761 i f ( chkVal<=0) then

chkVal := 1 ;763 end i f ;

i f ( ( nSt >=0) and ( nSt <= ParseTable .YYLAST)and ( mm check [ chkVal ] == cSt ) ) then

765 cSt := mm table [ nSt +1] ;else

767 cSt := mm defgoto [ n − ParseTable .YYNTOKENS+1] ;

end i f ;769 i f ( debug ) then

print ( ” [ nState : ” + intString ( cSt ) + ” ] ” ) ;771 end i f ;

s t a t eS tk := cSt : : s t a t eS tk ;773 end i f ;

env2 := ENV( cTok , nTk , s tateStk , errStk , er rSt , sSt , cSt , prog ,prgBk , astStk , debug , stateSkBk , astSkBk ) ;

775end reduce ;

777function t r a n s l a t e

779 input Integer tok1 ;input ParseData pt ;

781 output Integer tok2 ;

Page 144: OMCCp: A MetaModelica Based Parser Generator Applied to ...

124 APPENDIX C. PARSER GENERATOR

array<Integer> mm translate ;783 Integer maxT, uTok ;

algorithm785 PARSE TABLE( t r a n s l a t e=mm translate ) := pt ;

maxT := ParseTable .YYMAXUTOK;787 uTok := ParseTable .YYUNDEFTOK;

( tok2 ) := matchcontinue ( tok1<=maxT)789 local

Integer r e s ;791 case ( true )

equation793

r e s = mm translate [ tok1 ] ;795 // p r in t (”\nTRANSLATE TO: ” + i n t S t r i n g ( r e s ) ) ;

then ( r e s ) ;797 case ( fa l se )

then (uTok) ;799 end matchcontinue ;

end t r a n s l a t e ;801

function getTokenSemValue ” r e t r i e v e s semantic va lue from tokenid ”

803 input Integer tokenId ;input ParseData pt ;

805 output String tokenSemValue ” r e tu rn s semantic va lue o f thetoken ” ;

array<String> va lue s ;807 algorithm

809 i f ( Util . i sListEmpty ( ParseCode . lstSemValue )==true ) thenPARSE TABLE( tname=va lues ) := pt ;

811 elseva lue s := l i s t A r r a y ( ParseCode . lstSemValue ) ;

813 end i f ;tokenSemValue := ” ’ ” + va lue s [ tokenId ] + ” ’ ” ;

815 end getTokenSemValue ;

817 function p r i n t B u f f e rinput l i s t<Integer> i n L i s t ;

819 input String cBuf f ;output String outL i s t ;

821 l i s t<Integer> i n L i s t 2 ;algorithm

823 ( outL i s t ) := matchcontinue ( i nL i s t , cBuf f )local

825 Integer c ;String new, tout ;

827 l i s t<Integer> r e s t ;case ({} , )

829 then ( cBuf f ) ;else

831 equationc : : r e s t = i n L i s t ;

833 new = cBuff + intStr ingChar ( c ) ;( tout ) = p r i n t B u f f e r ( r e s t ,new) ;

835 then ( tout ) ;end matchcontinue ;

Page 145: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.1. PARSER.MO 125

837 end p r i n t B u f f e r ;

839 function printSemStackinput l i s t<String> i n L i s t ;

841 input String cBuf f ;output String outL i s t ;

843 l i s t<String> i n L i s t 2 ;algorithm

845 ( outL i s t ) := matchcontinue ( i nL i s t , cBuf f )local

847 String c ;String new, tout ;

849 l i s t<String> r e s t ;case ({} , )

851 then ( cBuf f ) ;else

853 equationc : : r e s t = i n L i s t ;

855 new = cBuff + ”\n” + c ;( tout ) = printSemStack ( r e s t ,new) ;

857 then ( tout ) ;end matchcontinue ;

859 end printSemStack ;

861 function printCandidateTokensinput l i s t<String> i n L i s t ;

863 input String cBuf f ;output String outL i s t ;

865 l i s t<String> i n L i s t 2 ;algorithm

867 ( outL i s t ) := matchcontinue ( i nL i s t , cBuf f )local

869 String c ;String new, tout ;

871 l i s t<String> r e s t ;case ({} , )

873 equationcBuf f = System . s u b s t r i n g ( cBuff , 1 , s t r ingLength ( cBuf f )

−4) ;875 then ( cBuf f ) ;

else877 equation

c : : r e s t = i n L i s t ;879 new = cBuff + c + ” or ” ;

( tout ) = printCandidateTokens ( r e s t ,new) ;881 then ( tout ) ;

end matchcontinue ;883 end printCandidateTokens ;

885 function pr in tStackinput l i s t<Integer> i n L i s t ;

887 input String cBuf f ;output String outL i s t ;

889 l i s t<Integer> i n L i s t 2 ;algorithm

891 ( outL i s t ) := matchcontinue ( i nL i s t , cBuf f )local

Page 146: OMCCp: A MetaModelica Based Parser Generator Applied to ...

126 APPENDIX C. PARSER GENERATOR

893 Integer c ;String new, tout ;

895 l i s t<Integer> r e s t ;case ({} , )

897 then ( cBuf f ) ;else

899 equationc : : r e s t = i n L i s t ;

901 new = cBuff + ” | ” + intString ( c ) ;( tout ) = pr in tStack ( r e s t ,new) ;

903 then ( tout ) ;end matchcontinue ;

905 end pr in tStack ;end Parser ;

C.2 ParserGenerator.mo

Listing C.2: ParserGenerator.mo

package ParserGenerator2 import System ;

import Util ;4 /∗

6 ∗/constant Boolean debug = fa l se ;

8constant String l eyend = ” Generated by OMCC v0 . 9 . 2 (

OpenModelica Compiler− Compiler ) Copyright 2011 Open SouceModelica Consorsium (OSMC) ” ;

10function genParser

12 input String b i s o n F i l e ;input String grammarFile ;

14 input String outFileName ;output String r e s u l t ;

16 String bisonCode , re , ar1 , r e s t ;Boolean res1 , res2 , res3 , r e s4 ;

18 l i s t<String> resu l tRegex , resTable , chars ;algorithm

20 //open bison f i l ei f ( outFileName<>”” and st r ingLength ( outFileName )<15) then

22 i f ( debug==true ) thenprint ( ”\nGenerating Parser from ” + b i s o n F i l e ) ;

24 end i f ;bisonCode := System . r e a d F i l e ( b i s o n F i l e ) ;

26 print ( ”\nReading BISON grammar f i l e ” + b i s o n F i l e ) ;r e s1 := bui ldParseTable ( bisonCode , ” ParseTable ” +

outFileName ) ;28 i f ( debug==true ) then

print ( ”\nGenerating Token from ” + b i s o n F i l e ) ;30 end i f ;

r e s 2 := buildTokens ( bisonCode , ”Token” + outFileName );

Page 147: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.2. PARSERGENERATOR.MO 127

32 i f ( debug==true ) thenprint ( ”\nGenerating ParserCode from ” + b i s o n F i l e )

;34 end i f ;

r e s 3 := bui ldParserCode ( bisonCode , grammarFile ,outFileName ) ;

36 i f ( debug==true ) thenprint ( ”\nBuild Parser . . . ” ) ;

38 end i f ;r e s 4 := bu i ldPar s e r ( outFileName ) ;

40r e s u l t := ” Parser Bu i l t ” ;

42 i f ( r e s1==fa l se ) thenr e s u l t := r e s u l t + ”\nParseTable ”+ outFileName +”

.mo could not be generated . ” ;44 end i f ;

i f ( r e s2==fa l se ) then46 r e s u l t := r e s u l t + ”\nToken”+ outFileName +” .mo

could not be generated . ” ;end i f ;

48 i f ( r e s3==fa l se ) thenr e s u l t := r e s u l t + ”\nParseCode”+ outFileName +” .

mo could not be generated . ” ;50 end i f ;

i f ( r e s4==fa l se ) then52 r e s u l t := r e s u l t + ”\nParser ”+ outFileName +” .mo

could not be generated . ” ;end i f ;

54 elser e s u l t := ” Parser can not be generated . I n v a l i d name” ;

56 end i f ;end genParser ;

58function bu i ldPar s e r

60 input String outFileName ;output Boolean bu i ldResu l t ;

62 String parser , r e s u l t , stTime , cp ;algorithm

64 par s e r := System . r e a d F i l e ( ” Parser .mo” ) ;stTime := getCurrentTimeStr ( ) ;

66 r e s u l t := System . s t r i ngRep la c e ( parser , ” ParseTable ” , ”ParseTable ” + outFileName ) ;

r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ” Lexer . ” , ” Lexer ” +outFileName + ” . ” ) ;

68 r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”ParseCode” , ”ParseCode” + outFileName ) ;

cp := ” package Parser ” + outFileName + ” \” ” + leyend +stTime + ”\”” ;

70 r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ” package Parser ” , cp ) ;r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”end Parser ; ” , ”end

Parser ” + outFileName + ” ; ” ) ;72 System . w r i t e F i l e ( ” Parser ” + outFileName + ” .mo” , r e s u l t ) ;

bu i ldResu l t := true ;74 end bu i ldPar s e r ;

76function readPro logEpi log

Page 148: OMCCp: A MetaModelica Based Parser Generator Applied to ...

128 APPENDIX C. PARSER GENERATOR

78 input String parserCode ;input String grammarFileName ;

80 output String parserCodeInc luded ;String grammarFile , ep i l og , prolog , re , ar1 , astRootType ;

82 Integer numMatches , pos1 , pos2 ;l i s t<String> r e su l tRegex ;

84 algorithmgrammarFile := System . r e a d F i l e ( grammarFileName ) ;

86// f i n d pro logue

88pos1 := System . s t r i ngF ind ( grammarFile , ”%{” ) ;

90 pos2 := System . s t r i ngF ind ( grammarFile , ”%}” ) ;

92 ar1 := System . s u b s t r i n g ( grammarFile , pos1+3,pos2−1) ;parserCodeInc luded := System . s t r i ngRep la c e ( parserCode , ”%

pro logue%” , ar1 ) ;94

//96 /∗ ar1 := System . s t r i n g F i n d S t r i n g ( grammarFile , ” AstTree ”) ;

pos1 := System . s t r ingF ind ( ar1 ,”=”) ;98 pos2 := System . s t r ingF ind ( ar1 , ” ; ” ) ;

astRootType := System . s ub s t r i n g ( ar1 , pos1 +2,pos2 ) ;100 astRootType := System . trim ( astRootType , ” ”) ;

parserCodeInc luded := System . s t r i ngRep la c e (parserCodeIncluded ,”% astTree %”,astRootType ) ; ∗/

102// f i n d ep i l o gue

104 re := ”%%” ;ar1 := System . s t r i n g F i n d S t r i n g ( grammarFile , r e ) ;

106 ar1 := System . s u b s t r i n g ( ar1 , 3 , s t r ingLength ( ar1 ) ) ;ar1 := System . s t r i n g F i n d S t r i n g ( ar1 , re ) ;

108 ar1 := System . s u b s t r i n g ( ar1 , 3 , s t r ingLength ( ar1 ) ) ;parserCodeInc luded := System . s t r i ngRep la c e (

parserCodeIncluded , ”%ep i l ogue%” , ar1 ) ;110

112 end readPro logEpi log ;

114function bui ldParserCode

116 input String bisonCode ;input String grammarFile ;

118 input String outFileName ;output Boolean bu i ldResu l t ;

120 l i s t<String> resTable ;String parseCode , r e s u l t , r e s t , stTime , cp , caseAction , re , typeTok

, as tStack122 , astStackVar , astValType , getValStack , setValStack ,

astRootType , i n i t S t a c k ;Integer i , numRules , pos , pos2 , posBegin , valBegin ;

124 l i s t<String> types , r e su l tRegex ;Integer maxReduce , numReduce , numMatches ;

126 algorithmtypes := {” St r ing ” , ” I n t e g e r ” } ;

128 maxReduce := 0 ;parseCode := System . r e a d F i l e ( ”ParseCode . tmo” ) ;

Page 149: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.2. PARSERGENERATOR.MO 129

130 stTime := leyend + getCurrentTimeStr ( ) ;r e s u l t := System . s t r i ngRep la c e ( parseCode , ”%ParseCode%” , ”

ParseCode” + outFileName ) ;132 r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%time%” , stTime ) ;

r e s u l t := readPro logEpi log ( r e s u l t , grammarFile ) ;134

136 caseAct ion := ”” ;resTable := {} ;

138 i f ( debug==true ) thenprint ( ”\nFind value ynru l e s . . . ” ) ;

140 end i f ;numRules := f indValue ( bisonCode , ”YYNRULES” ) ;

142 re := ” switch ( yyn ) ” ;r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;

144for i in 2 : numRules loop

146 cp := ”\n case ( ” ;resTable := cp : : resTable ;

148 cp := intString ( i ) ;re sTable := cp : : resTable ;

150 cp := ” , ) // ” ;resTable := cp : : resTable ;

152re := ” case ” + intString ( i ) + ” : ” ;

154 i f ( debug==true ) thenprint ( ”\n” + re ) ;

156 printAny ( ”\n” + re ) ;end i f ;

158 pos := System . s t r i ngF ind ( bisonCode , re ) ;i f ( pos<0) then

160 print ( ”\nError in r u l e ” + intString ( i )+ ” . Case not found . ” ) ;

end i f ;162 r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re

) ;

164 re := ”#l i n e ” ;pos := System . s t r i ngF ind ( r e s t , r e ) ;

166 pos2 := System . s t r i ngF ind ( r e s t , ” . y” ) ;cp := System . s u b s t r i n g ( r e s t , pos+1,pos2+3) ;

168 resTable := cp : : resTable ;pos2 := System . s t r i ngF ind ( r e s t , ” ;} ” ) ;

170 r e s t := System . s u b s t r i n g ( r e s t , 1 , pos2+3) ;// re := ” { [ ˆ } ] ∗ ; } ” ;

172 re := ” { . ∗ ; } ” ;( numMatches , r e su l tRegex ) := System . regex (

r e s t , re , 1 , false , fa l se ) ;174 r e s t : : := resu l tRegex ;

i f ( numMatches > 0) then176 cp := ”\n equat ion \n” ;

resTable := cp : : resTable ;178 i f ( debug==true ) then

print ( ”\n Rule : ” + r e s t ) ;180 end i f ;

( cp , numReduce , types ) :=processRule ( r e s t , types ) ;

Page 150: OMCCp: A MetaModelica Based Parser Generator Applied to ...

130 APPENDIX C. PARSER GENERATOR

182 i f ( maxReduce < numReduce )thenmaxReduce := numReduce ;

184 end i f ;r e sTable := cp : : resTable ;

186 cp := ”\n then ( ) ;\n ” ;resTable := cp : : resTable ;

188 elsei f ( debug==true ) then

190 print ( ”\nNot Found” ) ;end i f ;

192 end i f ;

194end for ;

196 resTable := l i s t R e v e r s e ( resTable ) ;caseAct ion := s t r i n g C h a r L i s t S t r i n g ( resTable ) ;

198

200 // generate v a r i a b l e s and typesStackastStack := ”” ;

202 astStack := ”” ;astStackVar := ”” ;

204 astValType := ”” ;getValStack := ”ASTSTACK( ” ;

206 setValStack := ” astStk2 := ASTSTACK( ” ;i n i t S t a c k := ”” ;

208 types := ”Token” : : types ; // s tack to push tokenswhile ( Util . i sListEmpty ( types )==fa l se ) loop

210 typeTok : : types := types ;

212 i f ( typeTok <> ” I n t e g e r ” and typeTok <> ” St r ing ” ) thenastStack := astStack + ” l i s t <” + typeTok + ”>

s tack ” + typeTok + ” ;\n” ;214 astStackVar := astStackVar + ” l i s t <” + typeTok + ”>

sk ” + typeTok + ” ;\n” ;astValType := astValType + ” ” + typeTok + ” v” +

typeTok + ” , ” ;216 else

astStack := astStack + ” l i s t <” + typeTok + ”>s tack ” + typeTok + ” ;\n” ;

218 astStackVar := astStackVar + ” l i s t <” + typeTok + ”>sk ” + typeTok + ” ;\n” ;

astValType := astValType + ” ” + typeTok + ” v” +typeTok + ” , ” ;

220 end i f ;for i in 1 : maxReduce loop

222 astValType := astValType + ” v” + intString ( i ) +typeTok ;i f ( i==maxReduce ) then

224 astValType := astValType + ” ;\n” ;else

226 astValType := astValType + ” , ” ;end i f ;

228 end for ;

230

Page 151: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.2. PARSERGENERATOR.MO 131

getValStack := getValStack + ” stack ” + typeTok + ”=sk ” +typeTok ;

232 setValStack := setValStack + ” sk ” + typeTok ;i f ( Util . i sListEmpty ( types )==fa l se ) then

234 getValStack := getValStack + ” , ” ;setValStack := setValStack + ” , ” ;

236 i n i t S t a c k := i n i t S t a c k + ” {} , ” ;else

238 getValStack := getValStack + ” ) := astStk ; ” ;setValStack := setValStack + ” ) ; ” ;

240 i n i t S t a c k := i n i t S t a c k + ”{}” ;end i f ;

242 end while ;

244 caseAct ion := astValType + caseAct ion ;

246 re := ” ( absyntree ) [ ” ;r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;

248 pos2 := System . s t r i ngF ind ( r e s t , ” ] ” ) ;astRootType := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1,pos2

) ;250

r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%astTree%” ,astRootType ) ;

252r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%i n i t S t a c k%” ,

i n i t S t a c k ) ;254

r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%caseAct ion%” ,caseAct ion ) ;

256 r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%astStack%” , astStack );

r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%astStackVar%” ,astStackVar ) ;

258 r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%GETASTSTACK%” ,getValStack ) ;

r e s u l t := System . s t r i ngRep la c e ( r e s u l t , ”%PUTASTSTACK%” ,setValStack ) ;

260System . w r i t e F i l e ( ”ParseCode” + outFileName + ” .mo” , r e s u l t ) ;

262 bu i ldResu l t := true ;end bui ldParserCode ;

264function processRule

266 input String r u l e ;input l i s t<String> types ;

268 output String proces sedRules ;output Integer numTk;

270 output l i s t<String> types2 ;Integer pos1 , pos2 , i ;

272 l i s t<String> resTable ;String c , cp , tokRes , re , typeTok ;

274 algorithmc := r u l e ;

276 resTable := {} ;cp := ” // reduce \n” ;

278 resTable := cp : : resTable ;

Page 152: OMCCp: A MetaModelica Based Parser Generator Applied to ...

132 APPENDIX C. PARSER GENERATOR

numTk := numTokens ( r u l e ) ;280 types2 := types ;

cp := ” ( in fo , skToken ) = g e t I n f o ( skToken , mm r2 [act ] ) ; \n” ;

282 resTable := cp : : resTable ;i f (numTk==0) then

284 cp := ” skSt r ing = reduceSt r ingStack ( skStr ing, mm r2 [ act ] ) ; \n” ;

resTable := cp : : resTable ;286 else

i := numTk;288 while ( i >0) loop

cp := reduceToken ( ru le , i ) ;290 resTable := cp : : resTable ;

typeTok := findTypeToken ( ru le , i ) ;292 i f ( Util . l i s t C o n t a i n s ( typeTok , types2 )==fa l se )

thentypes2 := typeTok : : types2 ;

294 end i f ;i := i −1;

296 end while ;end i f ;

298cp := ” // bu i ld \n” ;

300 resTable := cp : : resTable ;tokRes := f indTypeResult ( r u l e ) ;

302i f ( Util . l i s t C o n t a i n s ( tokRes , types2 )==fa l se ) then

304 types2 := tokRes : : types2 ;end i f ;

306 // re := ”( yyval ) [ ” + tokRes + ” ] ” ;re := ” ( yyval ) ” ;

308 pos1 := System . s t r i ngF ind ( ru le , r e ) ;i f ( pos1>=0) then

310cp := r u l e ;

312 i f (numTk>0) thenfor i in 1 :numTk loop

314 cp := replaceTokenVal ( cp , i ) ;i f ( debug==true ) then

316 print ( ”\n” + cp ) ;end i f ;

318 end for ;end i f ;

320 // r e p l a c e r e s u l t typere := ” ( yyval ) [ ” + tokRes + ” ] ” ;

322 cp := System . s t r i ngRep la c e ( cp , re , ”v” + tokRes ) ;i f ( tokRes==” St r ing ” ) then // d e f a u l t token

324 re := ” ( yyval ) ” ;cp := System . s t r i ngRep la c e ( cp , re , ”v” + tokRes )

;326 end i f ;

cp := System . s t r i ngRep la c e ( cp , ” ;} ” , ”” ) ;328 cp := System . s t r i ngRep la c e ( cp , ”{ ” , ” ” ) ;

i f ( debug==true ) then330 print ( ”\n replaceTokenVal : ” + cp ) ;

end i f ;

Page 153: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.2. PARSERGENERATOR.MO 133

332 resTable := cp : : resTable ;cp := ”\n // push Result \n ”

;334 resTable := cp : : resTable ;

cp := ” sk ” +tokRes + ”= v” + tokRes + ” : : sk ” +tokRes + ” ; \n” ;

336 resTable := cp : : resTable ;else

338 // root nodecp := r u l e ;

340 i f (numTk>0) thenfor i in 1 :numTk loop

342 cp := replaceTokenVal ( cp , i ) ;i f ( debug==true ) then

344 print ( ”\n” + cp ) ;end i f ;

346 end for ;end i f ;

348 // r e p l a c e r e s u l t typere := ”{ ( absyntree ) [ ” + tokRes + ” ] ” ;

350 cp := System . s t r i ngRep la c e ( cp , re , ” v” +tokRes ) ;

cp := System . s t r i ngRep la c e ( cp , ” ;} ” , ”” ) ;352 i f ( debug==true ) then

print ( ”\n replaceTokenRoot : ” + cp ) ;354 end i f ;

r e sTable := cp : : resTable ;356 cp := ”\n // push Result \n ”

;resTable := cp : : resTable ;

358 cp := ” sk ” +tokRes + ”= v” + tokRes + ” : : sk ” +tokRes + ” ; \n” ;

resTable := cp : : resTable ;360 end i f ;

362

364 resTable := l i s t R e v e r s e ( resTable ) ;proces sedRules := s t r i n g C h a r L i s t S t r i n g ( resTable ) ;

366 end processRule ;

368 function replaceTokenValinput String r u l e ;

370 input Integer tok ;output String r e s u l t ;

372 Integer pos , pos2 , numTok ;String re , r e s t , typeTok , cp ;

374 algorithmnumTok := numTokens ( r u l e ) ;

376 typeTok := findTypeToken ( ru le , tok ) ;re := ” ( yyvsp [ ( ” + intString ( tok ) + ” ) − ( ” + intString (

numTok) + ” ) ] ) [ ” + typeTok + ” ] ” ;378 pos := System . s t r i ngF ind ( ru le , re ) ;

i f ( pos<0) then380 re := ” ( yyvsp [ ( ” + intString ( tok ) + ” ) − ( ” + intString (

numTok) + ” ) ] ) ” ;end i f ;

Page 154: OMCCp: A MetaModelica Based Parser Generator Applied to ...

134 APPENDIX C. PARSER GENERATOR

382 cp := ” ( v” + intString ( tok ) + typeTok + ” ) ” ;i f ( f indTypeResult ( r u l e )==” I n t e g e r ” and typeTok==” St r ing ” )

then384 cp := ” ( s t r i n g I n t ( v” + intString ( tok ) + typeTok + ” ) ) ” ;

end i f ;386 // p r in t ( re ) ;

r e s u l t := System . s t r i ngRep la c e ( ru le , re , cp ) ;388 // p r in t ( r e s u l t ) ;

end replaceTokenVal ;390

function reduceToken392 input String r u l e ;

input Integer tok ;394 output String reduce ;

Integer pos , pos2 ;396 String re , r e s t , typeTok ;

algorithm398 typeTok := findTypeToken ( ru le , tok ) ;

reduce := ” v” + intString ( tok ) + typeTok +” : : sk ”+ typeTok + ” = sk ” + typeTok + ” ; \n” ;

400 // p r in t ( reduce ) ;end reduceToken ;

402function f indTypeResult

404 input String r u l e ;output String typeTok ;

406 Integer pos , pos2 , posAST ;String re , r e s t ;

408 algorithm// p r in t (”\n Rule−” + r u l e + ”−”) ;

410 re := ” ( absyntree ) [ ” ;posAST := System . s t r i ngF ind ( ru le , r e ) ;

412 re := ” ( yyval ) ” ;pos2 := System . s t r i ngF ind ( ru le , r e ) ;

414 re := ” ( yyval ) [ ” ;pos := System . s t r i ngF ind ( ru le , r e ) ;

416 i f ( pos>=0) thenr e s t := System . s t r i n g F i n d S t r i n g ( ru le , r e ) ;

418 pos2 := System . s t r i ngF ind ( r e s t , ” ] ” ) ;typeTok := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1,

pos2 ) ;420 e l s e i f (posAST>=0) then

re := ” ( absyntree ) [ ” ;422 r e s t := System . s t r i n g F i n d S t r i n g ( ru le , re ) ;

pos2 := System . s t r i ngF ind ( r e s t , ” ] ” ) ;424 typeTok := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1,

pos2 ) ;else

426 i f ( pos2>=0) thentypeTok := ” St r ing ” ;

428 end i f ;end i f ;

430 i f ( debug==true ) thenprint ( ”\n TypeTok−” + typeTok + ”−” ) ;

432 end i f ;end f indTypeResult ;

434

Page 155: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.2. PARSERGENERATOR.MO 135

function findTypeToken436 input String r u l e ;

input Integer tok ;438 output String typeTok ;

Integer pos , pos2 , numTok ;440 String re , r e s t ;

algorithm442 numTok := numTokens ( r u l e ) ;

r e := ” ( yyvsp [ ( ” + intString ( tok ) + ” ) − ( ” + intString (numTok) + ” ) ] ) [ ” ;

444pos := System . s t r i ngF ind ( ru le , r e ) ;

446i f ( pos<0) then

448 typeTok := ” St r ing ” ;else

450 r e s t := System . s u b s t r i n g ( ru le , pos+str ingLength ( re ) +1,s t r ingLength ( r u l e )−1) ;

pos2 := System . s t r i ngF ind ( r e s t , ” ] ” ) ;452 typeTok := System . s u b s t r i n g ( r e s t , 1 , pos2 ) ;

i f ( debug==true ) then454 print ( ”\nTypeToken [ ” + typeTok + ” ] ” ) ;

end i f ;456 end i f ;

458 end findTypeToken ;

460 function numTokensinput String r u l e ;

462 output Integer num;Integer pos , pos2 ;

464 String re , r e s t , va l ;algorithm

466 re := ” ) − ( ” ;pos := System . s t r i ngF ind ( ru le , r e ) ;

468i f ( pos<0) then

470 num := 0 ;else

472 r e s t := System . s t r i n g F i n d S t r i n g ( ru le , r e ) ;pos2 := System . s t r i ngF ind ( r e s t , ” ) ] ” ) ;

474va l := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1,pos2

) ;476 i f ( debug==true ) then

print ( ”\n found numTokens : ” + va l ) ;478 end i f ;

num := s t r i n g I n t ( va l ) ;480 end i f ;

end numTokens ;482

function f indValue484 input String bisonCode ;

input String v a r i a b l e ;486 output Integer value ;

Integer pos ;488 String r e s t , val , r e ;

Page 156: OMCCp: A MetaModelica Based Parser Generator Applied to ...

136 APPENDIX C. PARSER GENERATOR

algorithm490 re := ” d e f i n e ” + v a r i a b l e ;

r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;492 pos := System . s t r i ngF ind ( r e s t , ”\n” ) ;

va l := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1,pos ) ;494 i f ( debug==true ) then

print ( ”\n found value : ” + va l ) ;496 end i f ;

va lue := s t r i n g I n t ( va l ) ;498 end f indValue ;

500 function buildTokensinput String bisonCode ;

502 input String outFileName ;output Boolean bu i ldResu l t ;

504 String cp , re , ar1 , r e s t , r e s u l t , stTime , r e s t 2 ;Integer pos1 , pos2 , len , numMatches ;

506 l i s t<String> resu l tRegex , resTable , chars , tokens ;algorithm

508 stTime := leyend + getCurrentTimeStr ( ) ;cp := ” package ” + outFileName +” // ” + leyend + stTime ;

510 resTable := cp : : { } ;

512 // re := ”enum yytokentype {” ;re := ”enum yytokentype [ ˆ} ]∗} ” ;

514 ( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,false , fa l se ) ;

r e s t : : := resu l tRegex ;516 i f ( numMatches > 0) then

// r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;518 pos1 := System . s t r i ngF ind ( r e s t , ”{” ) ;

pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;520 end i f ;

r e s t := System . s u b s t r i n g ( r e s t , pos1+2,pos2−4) ;522 tokens := System . s t r t o k ( r e s t , ” , ” ) ;

while ( Util . i sListEmpty ( tokens )==fa l se ) loop524 cp := ”\n constant I n t e g e r ” ;

resTable := cp : : resTable ;526 cp : : tokens := tokens ;

cp := System . tr im ( cp , ”\n” ) ;528 resTable := cp : : resTable ;

cp := ” ; ” ;530 resTable := cp : : resTable ;

end while ;532

cp := ”\nend ” + outFileName + ” ; ” ;534 resTable := cp : : resTable ;

536 resTable := l i s t R e v e r s e ( resTable ) ;r e s u l t := s t r i n g C h a r L i s t S t r i n g ( resTable ) ;

538 System . w r i t e F i l e ( outFileName + ” .mo” , r e s u l t ) ;bu i ldResu l t := true ;

540 end buildTokens ;

542 function bui ldParseTableinput String bisonCode ;

544 input String outFileName ;

Page 157: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.2. PARSERGENERATOR.MO 137

output Boolean bu i ldResu l t ;546 String cp , re , ar1 , r e s t , r e s u l t , stTime ;

Integer pos1 , pos2 , len , numMatches ;548 l i s t<String> resu l tRegex , resTable , chars ;

algorithm550

stTime := leyend + getCurrentTimeStr ( ) ;552 cp := ” package ” + outFileName +” // ” + stTime + ” \n\

nconstant I n t e g e r YYFINAL = ” ;resTable := cp : : { } ;

554

556 // I n s e r t YYFINALre := ” d e f i n e YYFINAL” ;

558 r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos2 := System . s t r i ngF ind ( r e s t , ”\n” ) ;

560 ar1 := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1, pos2 ) ;resTable := ar1 : : re sTable ;

562cp := ” ;\n\nconstant I n t e g e r YYLAST = ” ;

564 resTable := cp : : resTable ;re := ”#d e f i n e YYLAST” ;

566 r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos2 := System . s t r i ngF ind ( r e s t , ”\n” ) ;

568 ar1 := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1, pos2 ) ;resTable := ar1 : : re sTable ;

570cp := ” ;\n\nconstant I n t e g e r YYNTOKENS =” ;

572 resTable := cp : : resTable ;re := ” d e f i n e YYNTOKENS” ;

574 r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos2 := System . s t r i ngF ind ( r e s t , ”\n” ) ;

576 ar1 := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1, pos2 ) ;resTable := ar1 : : re sTable ;

578cp := ” ;\n\nconstant I n t e g e r YYNNTS = ” ;

580 resTable := cp : : resTable ;re := ” d e f i n e YYNNTS” ;

582 r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos2 := System . s t r i ngF ind ( r e s t , ”\n” ) ;

584 ar1 := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1, pos2 ) ;resTable := ar1 : : re sTable ;

586cp := ” ;\n\nconstant I n t e g e r YYNRULES = ” ;

588 resTable := cp : : resTable ;re := ” d e f i n e YYNRULES” ;

590 r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos2 := System . s t r i ngF ind ( r e s t , ”\n” ) ;

592 ar1 := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1, pos2 ) ;resTable := ar1 : : re sTable ;

594cp := ” ;\n\nconstant I n t e g e r YYNSTATES = ” ;

596 resTable := cp : : resTable ;re := ” d e f i n e YYNSTATES” ;

598 r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos2 := System . s t r i ngF ind ( r e s t , ”\n” ) ;

600 ar1 := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1, pos2 ) ;

Page 158: OMCCp: A MetaModelica Based Parser Generator Applied to ...

138 APPENDIX C. PARSER GENERATOR

resTable := ar1 : : re sTable ;602

cp := ” ;\n\nconstant I n t e g e r YYUNDEFTOK = ” ;604 resTable := cp : : resTable ;

r e := ” d e f i n e YYUNDEFTOK” ;606 r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;

pos2 := System . s t r i ngF ind ( r e s t , ”\n” ) ;608 ar1 := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1,pos2 ) ;

resTable := ar1 : : re sTable ;610

cp := ” ;\n\nconstant I n t e g e r YYMAXUTOK = ” ;612 resTable := cp : : resTable ;

r e := ” d e f i n e YYMAXUTOK” ;614 r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;

pos2 := System . s t r i ngF ind ( r e s t , ”\n” ) ;616 ar1 := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1,pos2 ) ;

resTable := ar1 : : re sTable ;618

cp := ” ;\n\nconstant I n t e g e r YYPACT NINF = ” ;620 resTable := cp : : resTable ;

r e := ” d e f i n e YYPACT NINF” ;622 r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;

pos2 := System . s t r i ngF ind ( r e s t , ”\n” ) ;624 ar1 := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1,pos2 ) ;

resTable := ar1 : : re sTable ;626

cp := ” ;\n\nconstant I n t e g e r YYTABLE NINF = ” ;628 resTable := cp : : resTable ;

r e := ” d e f i n e YYTABLE NINF” ;630 r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;

pos2 := System . s t r i ngF ind ( r e s t , ”\n” ) ;632 ar1 := System . s u b s t r i n g ( r e s t , s t r ingLength ( re ) +1,pos2 ) ;

resTable := ar1 : : re sTable ;634

cp := ” ;\n\nconstant l i s t <Integer> y y t r a n s l a t e = {\n” ;636 resTable := cp : : resTable ;

// re := ” s t a t i c const yytype u int8 y y t r a n s l a t e ” ;638 re := ” y y t r a n s l a t e \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;

( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,false , fa l se ) ;

640 r e s t : : := resu l tRegex ;i f ( numMatches > 0) then

642 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;

644 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;ar1 := System . s u b s t r i n g ( r e s t , pos1+2,pos2−1) ;

646 resTable := ar1 : : resTable ;end i f ;

648cp := ” } ;\n\nconstant l i s t <Integer> yyprhs = {\n” ;

650 resTable := cp : : resTable ;// re := ” s t a t i c const yytype u int8 yyprhs ” ;

652 re := ” yyprhs \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,

false , fa l se ) ;654 r e s t : : := resu l tRegex ;

i f ( numMatches > 0) then

Page 159: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.2. PARSERGENERATOR.MO 139

656 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;

658 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;ar1 := System . s u b s t r i n g ( r e s t , pos1+2,pos2−1) ;

660 resTable := ar1 : : resTable ;end i f ;

662cp := ” } ;\n\nconstant l i s t <Integer> yyrhs = ” ;

664 resTable := cp : : resTable ;// re := ” s t a t i c const yytype in t8 yyrhs ” ;

666 re := ” yyrhs \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,

false , fa l se ) ;668 r e s t : : := resu l tRegex ;

i f ( numMatches > 0) then670 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;

pos1 := System . s t r i ngF ind ( r e s t , ”{” ) ;672 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;

ar1 := System . s u b s t r i n g ( r e s t , pos1+1, pos2+1) ;674 resTable := ar1 : : resTable ;

end i f ;676

cp := ” ;\n\nconstant l i s t <Integer> y y r l i n e := {\n” ;678 resTable := cp : : resTable ;

re := ” s t a t i c const yytype u int8 y y r l i n e ” ;680 re := ” y y r l i n e \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;

( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,false , fa l se ) ;

682 r e s t : : := resu l tRegex ;i f ( numMatches > 0) then

684 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;

686 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;ar1 := System . s u b s t r i n g ( r e s t , pos1+2,pos2−1) ;

688 resTable := ar1 : : resTable ;end i f ;

690cp := ” } ;\n\nconstant l i s t <Str ing> yytname = {\n” ;

692 resTable := cp : : resTable ;// re := ” s t a t i c const char ∗ const yytname ” ;

694 re := ”yytname [ ˆ} ]∗} ” ;( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,

false , fa l se ) ;696

r e s t : : := resu l tRegex ;698 // p r in t (”\nNumMatches : ” + i n t S t r i n g ( numMatches ) + ”\n” +

r e s t ) ;i f ( numMatches > 0) then

700 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;

702 pos2 := System . s t r i ngF ind ( r e s t , ” , 0” ) ;ar1 := System . s u b s t r i n g ( r e s t , pos1+2, pos2 ) ;

704 resTable := ar1 : : resTable ;end i f ;

706cp := ” } ;\n\nconstant l i s t <Integer> yytoknum = {\n” ;

708 resTable := cp : : resTable ;

Page 160: OMCCp: A MetaModelica Based Parser Generator Applied to ...

140 APPENDIX C. PARSER GENERATOR

// re := ” s t a t i c const yytype u int16 yytoknum ” ;710 re := ”yytoknum \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;

( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,false , fa l se ) ;

712 r e s t : : := resu l tRegex ;i f ( numMatches > 0) then

714 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;

716 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;ar1 := System . s u b s t r i n g ( r e s t , pos1+2,pos2−1) ;

718 resTable := ar1 : : resTable ;end i f ;

720cp := ” } ;\n\nconstant l i s t <Integer> yyr1 = {\n” ;

722 resTable := cp : : resTable ;// re := ” s t a t i c const yytype u int8 yyr1 ” ;

724 re := ” yyr1 \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,

false , fa l se ) ;726 r e s t : : := resu l tRegex ;

i f ( numMatches > 0) then728 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;

pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;730 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;

ar1 := System . s u b s t r i n g ( r e s t , pos1+2,pos2−1) ;732 resTable := ar1 : : resTable ;

end i f ;734

cp := ” } ;\n\nconstant l i s t <Integer> yyr2 = {\n” ;736 resTable := cp : : resTable ;

// re := ” s t a t i c const yytype u int8 yyr2 ” ;738 re := ” yyr2 \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;

( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,false , fa l se ) ;

740 r e s t : : := resu l tRegex ;i f ( numMatches > 0) then

742 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos1 := System . s t r i ngF ind ( r e s t , ” , ” ) ;

744 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;ar1 := System . s u b s t r i n g ( r e s t , pos1+2,pos2−1) ;

746 resTable := ar1 : : resTable ;end i f ;

748cp := ” } ;\n\nconstant l i s t <Integer> yyde fact = ” ;

750 resTable := cp : : resTable ;// re := ” s t a t i c const yytype u int8 yyde fact ” ;

752 re := ” yyde fact \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,

false , fa l se ) ;754 r e s t : : := resu l tRegex ;

i f ( numMatches > 0) then756 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;

pos1 := System . s t r i ngF ind ( r e s t , ”{” ) ;758 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;

ar1 := System . s u b s t r i n g ( r e s t , pos1+1, pos2+1) ;760 resTable := ar1 : : resTable ;

end i f ;

Page 161: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.2. PARSERGENERATOR.MO 141

762cp := ” ;\n\nconstant l i s t <Integer> yydefgoto = ” ;

764 resTable := cp : : resTable ;// re := ” s t a t i c const yytype in t8 yydefgoto ” ;

766 re := ” yydefgoto \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,

false , fa l se ) ;768 r e s t : : := resu l tRegex ;

i f ( numMatches > 0) then770 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;

pos1 := System . s t r i ngF ind ( r e s t , ”{” ) ;772 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;

ar1 := System . s u b s t r i n g ( r e s t , pos1+1, pos2+1) ;774 resTable := ar1 : : resTable ;

end i f ;776

cp := ” ;\n\nconstant l i s t <Integer> yypact = ” ;778 resTable := cp : : resTable ;

// re := ” s t a t i c const yytype in t8 yypact ” ;780 re := ” yypact \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;

( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,false , fa l se ) ;

782 r e s t : : := resu l tRegex ;i f ( numMatches > 0) then

784 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos1 := System . s t r i ngF ind ( r e s t , ”{” ) ;

786 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;ar1 := System . s u b s t r i n g ( r e s t , pos1+1, pos2+1) ;

788 resTable := ar1 : : resTable ;end i f ;

790cp := ” ;\n\nconstant l i s t <Integer> yypgoto = ” ;

792 resTable := cp : : resTable ;// re := ” s t a t i c const yytype in t8 yypgoto ” ;

794 re := ”yypgoto \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,

false , fa l se ) ;796 r e s t : : := resu l tRegex ;

i f ( numMatches > 0) then798 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;

pos1 := System . s t r i ngF ind ( r e s t , ”{” ) ;800 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;

ar1 := System . s u b s t r i n g ( r e s t , pos1+1, pos2+1) ;802 resTable := ar1 : : resTable ;

end i f ;804

cp := ” ;\n\nconstant l i s t <Integer> yytab le = ” ;806 resTable := cp : : resTable ;

// re := ” s t a t i c const yytype u int8 yytab le ” ;808 re := ” yytab le \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;

( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,false , fa l se ) ;

810 r e s t : : := resu l tRegex ;i f ( numMatches > 0) then

812 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos1 := System . s t r i ngF ind ( r e s t , ”{” ) ;

814 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;

Page 162: OMCCp: A MetaModelica Based Parser Generator Applied to ...

142 APPENDIX C. PARSER GENERATOR

ar1 := System . s u b s t r i n g ( r e s t , pos1+1, pos2+1) ;816 resTable := ar1 : : resTable ;

end i f ;818

cp := ” ;\n\nconstant l i s t <Integer> yycheck =” ;820 resTable := cp : : resTable ;

// re := ” s t a t i c const yytype in t8 yycheck ” ;822 re := ” yycheck \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;

( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,false , fa l se ) ;

824 r e s t : : := resu l tRegex ;i f ( numMatches > 0) then

826 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;pos1 := System . s t r i ngF ind ( r e s t , ”{” ) ;

828 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;ar1 := System . s u b s t r i n g ( r e s t , pos1+1, pos2+1) ;

830 resTable := ar1 : : resTable ;end i f ;

832cp := ” ;\n\nconstant l i s t <Integer> yystos = ” ;

834 resTable := cp : : resTable ;// re := ” s t a t i c const yytype u int8 yystos ” ;

836 re := ” yystos \\ [ [ 0 −9 ]∗\\ ] =[ˆ} ]∗} ” ;( numMatches , r e su l tRegex ) := System . regex ( bisonCode , re , 1 ,

false , fa l se ) ;838 r e s t : : := resu l tRegex ;

i f ( numMatches > 0) then840 // r e s t := System . s t r i n g F i n d S t r i n g ( bisonCode , re ) ;

pos1 := System . s t r i ngF ind ( r e s t , ”{” ) ;842 pos2 := System . s t r i ngF ind ( r e s t , ”}” ) ;

ar1 := System . s u b s t r i n g ( r e s t , pos1+1, pos2+1) ;844 resTable := ar1 : : resTable ;

end i f ;846

cp := ” ;\n\nend ” + outFileName + ” ; ” ;848 resTable := cp : : resTable ;

850 resTable := l i s t R e v e r s e ( resTable ) ;r e s u l t := s t r i n g C h a r L i s t S t r i n g ( resTable ) ;

852 System . w r i t e F i l e ( outFileName + ” .mo” , r e s u l t ) ;bu i ldResu l t := true ;

854 end bui ldParseTable ;

856 public function getCurrentTimeStr ”r e tu rn s cur rent time in format Www Mmm dd hh :mm: s s yyyy

858 us ing the asct ime ( ) func t i on in time . h ( l i b c )”

860 output String t imeStr ;Integer sec , min , hour , mday , mon , year ;

862 algorithmt imeStr := System . getCurrentTimeStr ( ) ;

864 /∗ ( sec , min , hour , mday , mon , year ) := System .getCurrentDateTime ( ) ;

t imeStr := i n t S t r i n g ( year ) + ”/” + i n t S t r i n g (mon)+ ”/” +i n t S t r i n g (mday)+

866 ” ” + i n t S t r i n g ( hour )+ ” :” + i n t S t r i n g ( min ) + ” :” +i n t S t r i n g ( s ec ) ; ∗/

Page 163: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.3. PARSECODE.TMO 143

end getCurrentTimeStr ;868

870 public function subs t r i ng3input String i n S t r i n g ;

872 input Integer s t a r t ;input Integer stop ;

874 output String outSt r ing ;l i s t<String> chars , r e s u l t ;

876 String c ;Integer i ;

878 algorithm

880 r e s u l t :={} ;chars := s t r i n g L i s t S t r i n g C h a r ( i n S t r i n g ) ;

882 for i in 1 : stop loopc : : chars := chars ;

884 i f ( i>=s t a r t ) thenr e s u l t := c : : r e s u l t ;

886 end i f ;end for ;

888 r e s u l t := l i s t R e v e r s e ( r e s u l t ) ;outSt r ing := s t r i n g C h a r L i s t S t r i n g ( r e s u l t ) ;

890 end subs t r i ng3 ;

892 end ParserGenerator ;

C.3 ParseCode.tmo

Listing C.3: ParseCode.tmo

package %ParseCode% // %time%2 import Types ;

4 %pro logue%

6 uniontype AstStackrecord ASTSTACK

8 %astStack% end ASTSTACK;record EMPTY end EMPTY;

10 end AstStack ;

12 function i n i tAs tS tackinput AstStack astStack ;

14 output AstStack astStack2 ;algorithm

16 astStack2 := ASTSTACK(% i n i t S t a c k %) ;end i n i tAs tS tack ;

18function getAST ” re tu rn s the AST b u i l t by the par s ing ”

20 input AstStack astStk ”MultiTypedStack used by the par s e r ” ;output AstTree as t ” r e tu rn s the AST in the f i n a l type o f the

t r e e ” ;22 l i s t<%astTree%> r e tStk ;

Page 164: OMCCp: A MetaModelica Based Parser Generator Applied to ...

144 APPENDIX C. PARSER GENERATOR

algorithm24 ASTSTACK( stack%astTree%=retStk ) := astStk ;

a s t : : := re tStk ;26 end getAST ;

28

30 function actionRedinput Integer act ;

32 input AstStack astStk ;input array<Integer> mm r2 ;

34 output AstStack astStk2 ;output Boolean e r r o r=fa l se ;

36 output String errorMsg=”” ;OMCCTypes . In f o i n f o ;

38 // env v a r i a b l e s// AstStack

40 %astStackVar%

42algorithm

44// pr intContentStack ( astStk ) ;

46 // printAny (” r u l e : ” + i n t S t r i n g ( act ) ) ;%GETASTSTACK%

48 ( ) := matchcontinue ( act , as tStk )local

50 // l o c a l v a r i a b l e s%caseAct ion%

52 case ( , )equation

54 //lAST = i n t S t r i n g ( act ) ;errorMsg = ”\n” + OMCCTypes . p r i n t I n f o E r r o r ( i n f o ) + ” :

I l e g a l a c t i on case ” + intString ( act ) ;56 e r r o r = true ;

then ( ) ;58 end matchcontinue ;

%PUTASTSTACK%60 /∗ astStk2 := ASTSTACK( idStk , inStk , boStk , roStk , exStk , i l S t k ,

s tStk ) ; ∗/

62 end actionRed ;

64 function r educeSt r ingStackinput l i s t<String> skS t r ing ;

66 input Integer nTokens ;output l i s t<String> skStr ingRes ;

68 String strReduce ;Integer i ;

70 algorithmfor i in 1 : nTokens loop

72 strReduce : : s kS t r ing := skSt r ing ;end for ;

74 skStr ingRes := skSt r ing ;end r educeSt r ingStack ;

76function g e t I n f o

Page 165: OMCCp: A MetaModelica Based Parser Generator Applied to ...

C.3. PARSECODE.TMO 145

78 input l i s t<Token> skToken ;input Integer nTokens ;

80 output OMCCTypes . In f o i n f o ;output l i s t<Token> skTokenRes ;

82 Token token ;OMCCTypes . In f o tmpInfo ;

84 Integer lns , cns , lne , cne , i ;String fn ;

86 algorithmfor i in 1 : nTokens loop

88 token : : skToken := skToken ;OMCCTypes .TOKEN( l o c=i n f o ) := token ;

90 i f ( i==nTokens ) thenOMCCTypes . INFO( f i leName=fn , l ineNumberStart=lns ,

columnNumberStart=cns ) := i n f o ;92 end i f ;

i f ( i ==1) then94 OMCCTypes . INFO( lineNumberEnd=lne , columnNumberEnd=cne ) :=

i n f o ;end i f ;

96 end for ;i f ( nTokens==0) then

98 token : : := skToken ;OMCCTypes .TOKEN( l o c=i n f o ) := token ;

100 OMCCTypes . INFO( f i leName=fn , l ineNumberStart=lns ,columnNumberStart=cns , lineNumberEnd=lne , columnNumberEnd=cne ) := i n f o ;

end i f ;102 i n f o := OMCCTypes . INFO( fn , false , lns , cns , lne , cne ,OMCCTypes .

getTimeStamp ( ) ) ;token := OMCCTypes .TOKEN( ”grupped” ,0 ,{} , i n f o ) ;

104 skTokenRes := token : : skToken ;end g e t I n f o ;

106function push

108 input AstStack astStk ;input String inVal ;

110 input OMCCTypes . Token token ;output AstStack astStk2 ;

112 // AstStack%astStackVar%

114 algorithm%GETASTSTACK%

116 skSt r ing := inVal : : s kS t r ing ;skToken := token : : skToken ;

118 %PUTASTSTACK%end push ;

120%ep i l ogue%

122end %ParseCode%;

Page 166: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Appendix D

Sample Input

D.1 lexer10.l

Listing D.1: lexer10.l

1 %{#inc lude <s t d l i b . h>

3 #d e f i n e YYSTYPE void∗#inc lude ” par s e r . h”

5

7 #i f d e f RML#inc lude ” y a c c l i b . h”

9 #inc lude ”Absyn . h”#else

11 #inc lude ” meta model ica . h”extern s t r u c t r e c o r d d e s c r i p t i o n Absyn Exp INT desc ;

13 #d e f i n e Absyn INT (X1) (mmc mk box2(3 ,& Absyn Exp INT desc, X1) )

#e n d i f15

int absyn in t ege r (char ∗ s ) ;17 int absyn ident or keyword (char ∗ s ) ;

int yywrap ( ) ;19 %}

21 %opt ion yy l ineno

23 %x c comment

25 whitespace [ \ t \n]+l e t t e r [ a−zA−Z ]

27 ident { l e t t e r }({ l e t t e r } |{ d i g i t }) ∗d i g i t [0−9]

29 d i g i t s { d i g i t}+icon { d i g i t s }

31 /∗ Lex s t y l e l e x i c a l syntax o f tokens in the PAM language ∗/

146

Page 167: OMCCp: A MetaModelica Based Parser Generator Applied to ...

D.2. PARSER10.Y 147

33 %%

35 {whitespace } ;” whi l e ” return T WHILE;

37 ”do” return T DO;” e l s e ” return T ELSE ;

39 ”end” return T END;” e n d i f ” return T ENDIF ;

41 ” i f ” return T IF ;” read ” return T READ;

43 ” then ” return T THEN;” wr i t e ” return T WRITE;

45 { i d ent } return T IDENT ;{ d i g i t s } return T INTCONST;

47 ”:=” return T ASSIGN ;”+” return T ADD;

49 ”−” return T SUB ;”∗” return T MUL;

51 ”/” return T DIV ;” ( ” return T LPAREN;

53 ” ) ” return T RPAREN;”<” return T LT ;

55 ”<=” return T LE ;”=” return T EQ;

57 ”<>” return T NE ;”>=” return T GE;

59 ”>” return T GT;” ; ” return T SEMIC ;

61

63 ”/\∗” {BEGIN( c comment ) ;

65 }<c comment>

67 {”\∗/” { BEGIN( INITIAL ) ; }

69 ”/\∗” { yyer ro r ( ” Susp i c i ou s comment” ) ; }[ ˆ\n ] ;

71 \n ;<<EOF>> {

73 yyer ro r ( ”Unterminated comment” ) ;yyterminate ( ) ;

75 }}

77%%

79int yywrap ( )

81 {return 1 ;

83 }

D.2 parser10.y

Page 168: OMCCp: A MetaModelica Based Parser Generator Applied to ...

148 APPENDIX D. SAMPLE INPUT

Listing D.2: parser10.y

1 %{type AstTree = Absyn . Stmt ;

3 type Stmt = Absyn . Stmt ;type IdentLst = Absyn . IdentLst ;

5 type Ident = Absyn . Ident ;type Exp = Absyn . Exp ;

7 type BinOp = Absyn . BinOp ;type RelOp = Absyn . RelOp ;

9constant l i s t<String> lstSemValue2 = {} ;

11constant l i s t<String> lstSemValue = {

13 ” e r r o r ” , ” undetermined ” , ” read ” , ” wr i t e ” , ”:=” ,” i f ” , ” then ” , ” e n d i f ” , ” e l s e ” , ” to ” ,

15 ”do” , ”end” , ” whi l e ” , ” ( ” , ” ) ” ,” I d e n t i t y ” , ” I n t e g e r ” , ”=” , ”<=” , ”<” ,

17 ”>” , ”>=” , ”<>” , ”+” , ”−” ,”∗” , ”/” , ” ; ” , ”” } ;

19%}

21%token T READ

23 %token T WRITE%token T ASSIGN

25 %token T IF%token T THEN

27 %token T ENDIF%token T ELSE

29 %token T TO%token T DO

31 %token T END%token T WHILE

33 %token T LPAREN%token T RPAREN

35 %token T IDENT%token T INTCONST

37 %token T EQ%token T LE

39 %token T LT%token T GT

41 %token T GE%token T NE

43 %token T ADD%token T SUB

45 %token T MUL%token T DIV

47 %token T SEMIC

49 %%

51 /∗ Yacc BNF grammar o f the PAM language ∗/

53 program/∗Stmt∗/ : s e r i e s{ ( absyntree ) [ Stmt ] = $1 [ Stmt ] ;

}

Page 169: OMCCp: A MetaModelica Based Parser Generator Applied to ...

D.2. PARSER10.Y 149

55 s e r i e s /∗Stmt∗/ : statement{ $$ [ Stmt ] = Absyn .SEQ( $1 [ Stmt ] ,

Absyn . SKIP ( ) ) ; }57 | statement s e r i e s

{ $$ [ Stmt ] = Absyn .SEQ( $1 [ Stmt ] ,$2 [ Stmt ] ) ; }

59statement /∗Stmt∗/ : input s tatement T SEMIC

61 { $$ [ Stmt ] = $1 [ Stmt ] ; }| output statement T SEMIC

63 { $$ [ Stmt ] = $1 [ Stmt ] ; }| ass ignment statement T SEMIC

65 { $$ [ Stmt ] = $1 [ Stmt ] ; }| c o n d i t i o n a l s t a t e m e n t

67 { $$ [ Stmt ] = $1 [ Stmt ] ; }| d e f i n i t e l o o p

69 { $$ [ Stmt ] = $1 [ Stmt ] ; }| w h i l e l o o p

71 { $$ [ Stmt ] = $1 [ Stmt ] ; }

73 input s tatement /∗Stmt∗/ : T READ v a r i a b l e l i s t{ $$ [ Stmt ] = Absyn .READ( $2 [

IdentLst ] ) ; }75

output statement /∗Stmt∗/ : T WRITE v a r i a b l e l i s t77 { $$ [ Stmt ] = Absyn .WRITE( $2 [

IdentLst ] ) ; }

79 v a r i a b l e l i s t /∗ IdentLst ∗/ : v a r i a b l e{ $$ [ IdentLst ] = $1 [ Ident ] : : { } ;

}81 | v a r i a b l e v a r i a b l e l i s t

{ $$ [ IdentLst ] = $1 [ Ident ] : : $2 [IdentLst ] ; }

83ass ignment statement /∗Stmt∗/ : v a r i a b l e T ASSIGN expr e s s i on

85 { $$ [ Stmt ] = Absyn . ASSIGN( $1 [Ident ] , $3 [ Exp ] ) ; }

87 c o n d i t i o n a l s t a t e m e n t /∗Stmt∗/ : T IF comparison T THEN s e r i e sT ENDIF

{ $$ [ Stmt ] = Absyn . IF ( $2 [ Exp ] ,$4 [ Stmt ] , Absyn . SKIP ( ) ) ; }

89 | T IF comparison T THEN s e r i e sT ELSE s e r i e s T ENDIF

91 { $$ [ Stmt ] = Absyn . IF ( $2 [ Exp ] ,$4 [ Stmt ] , $6 [ Stmt ] ) ; }

93 d e f i n i t e l o o p /∗Stmt∗/ : T TO expre s s i on T DO s e r i e sT END

{ $$ [ Stmt ] = Absyn .TODO( $2 [ Exp ] ,$4 [ Stmt ] ) ; }

95w h i l e l o o p /∗Stmt∗/ : T WHILE comparison T DO s e r i e s

T END97 { $$ [ Stmt ] = Absyn .WHILE( $2 [ Exp

] , $4 [ Stmt ] ) ; }

Page 170: OMCCp: A MetaModelica Based Parser Generator Applied to ...

150 APPENDIX D. SAMPLE INPUT

99 exp r e s s i on /∗Exp∗/ : term{ $$ [ Exp ] = $1 [ Exp ] ; }

101 | exp r e s s i on weak operator term{ $$ [ Exp ] = Absyn .BINARY( $1 [ Exp

] , $2 [ BinOp ] , $3 [ Exp ] ) ; }103

term/∗Exp∗/ : element105 { $$ [ Exp ] = $1 [ Exp ] ; }

| term s t r o n g o p e r a t o r element107 { $$ [ Exp ] = Absyn .BINARY( $1 [ Exp

] , $2 [ BinOp ] , $3 [ Exp ] ) ; }

109 element /∗Exp∗/ : constant{ $$ [ Exp ] = Absyn . INT( $1 [ Integer

] ) ; }111 | v a r i a b l e

{ $$ [ Exp ] = Absyn .IDENT( $1 [ Ident] ) ; }

113 | T LPAREN expr e s s i on T RPAREN{ $$ [ Exp ] = $2 [ Exp ] ; }

115comparison /∗Exp∗/ : exp r e s s i on r e l a t i o n exp r e s s i on

117 { $$ [ Exp ] = Absyn .RELATION( $1 [Exp ] , $2 [ RelOp ] , $3 [ Exp ] ) ; }

119 v a r i a b l e /∗ St r ing ∗/ : T IDENT{ $$ [ Ident ] = $1 ; }

121 constant /∗ I n t e g e r ∗/ : T INTCONST{ $$ [ Integer ] = $1 ; }

123r e l a t i o n /∗RelOp∗/ : T EQ { $$ [ RelOp ] = Absyn .EQ( ) ;}

125 | T LE { $$ [ RelOp ] = Absyn .LE( ) ;}| T LT { $$ [ RelOp ] = Absyn .LT( ) ;}

127 | T GT { $$ [ RelOp ] = Absyn .GT( ) ;}| T GE { $$ [ RelOp ] = Absyn .GE( ) ;}

129 | T NE { $$ [ RelOp ] = Absyn .NE( ) ;}

131 weak operator /∗BinOp∗/ : T ADD { $$ [ BinOp ] = Absyn .ADD( ) ;}| T SUB { $$ [ BinOp ] = Absyn .SUB( ) ;}

133s t r o n g o p e r a t o r /∗BinOp∗/ : T MUL { $$ [ BinOp ] = Absyn .MUL( ) ;}

135 | T DIV { $$ [ BinOp ] = Absyn . DIV( ) ;}

137 %%

139 function printAST ” p r i n t the AST b u i l t by the par s ing ”input AstStack astStk ”MultiTypedStack used by the par s e r ” ;

141 output AstTree as t ” r e tu rn s the AST in the f i n a l type o f thet r e e ” ;

l i s t<Absyn . Stmt> r e tStk ;143 algorithm

ASTSTACK( stackStmt=retStk ) := astStk ;145 printAny ( as t ) ;

a s t : : := re tStk ;147 end printAST ;

Page 171: OMCCp: A MetaModelica Based Parser Generator Applied to ...

D.2. PARSER10.Y 151

149 function getSemValue ” r e t r i e v e s semval from tokens ”input Integer tokenId ;

151 output String tokenSemValue ” r e tu rn s semantic va lue o f thetoken ” ;

array<String> va lue s ;153 algorithm

va lue s := l i s t A r r a y ( lstSemValue ) ;155 tokenSemValue := va lue s [ tokenId ] ;

end getSemValue ;

Page 172: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Appendix E

Sample Output

These output files are from the Exercise 10 from the MetaModelica guide[Fritzson and Pop, 2011a].

E.1 ParseTable10.mo

Listing E.1: ParseTable10.mo

package ParseTable10 // generated by OMCC v0 . 7 Fr i Apr 2917 : 00 : 58 2011

2

4 constant Integer YYFINAL = 30 ;

6 constant Integer YYLAST = 71 ;

8 constant Integer YYNTOKENS = 29 ;

10 constant Integer YYNNTS = 20 ;

12 constant Integer YYNRULES = 39 ;

14 constant Integer YYNSTATES = 68 ;

16 constant Integer YYUNDEFTOK = 2 ;

18 constant Integer YYMAXUTOK = 283 ;

20 constant Integer YYPACT NINF = −20;

22 constant Integer YYTABLE NINF = −1;

24 constant l i s t<Integer> y y t r a n s l a t e = {2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,

26 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

152

Page 173: OMCCp: A MetaModelica Based Parser Generator Applied to ...

E.1. PARSETABLE10.MO 153

2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

28 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

30 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

32 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

34 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

36 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

38 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

40 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

42 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

44 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

46 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

48 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 ,

50 2 , 2 , 2 , 2 , 2 , 2 , 1 , 2 ,3 , 4 ,

5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ,13 , 14 ,

52 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 ,23 , 24 ,

25 , 26 , 27 , 28} ;54

constant l i s t<Integer> yyprhs = {56 0 , 3 , 5 , 7 , 10 , 13 , 16 , 19 , 21 ,

Page 174: OMCCp: A MetaModelica Based Parser Generator Applied to ...

154 APPENDIX E. SAMPLE OUTPUT

23 , 25 , 28 , 31 , 33 , 36 , 40 , 46 ,54 , 60 ,

58 66 , 68 , 72 , 74 , 78 , 80 , 82 , 86 ,90 , 92 ,

94 , 96 , 98 , 100 , 102 , 104 , 106 , 108 ,110 , 112} ;

60constant l i s t<Integer> yyrhs = {

62 30 , 0 , −1, 31 , −1, 32 , −1, 32 ,31 , −1,

33 , 28 , −1, 34 , 28 , −1, 36 , 28 ,−1, 37 ,

64 −1, 38 , −1, 39 , −1, 3 , 35 , −1,4 , 35 ,

−1, 44 , −1, 44 , 35 , −1, 44 , 5 ,40 , −1,

66 6 , 43 , 7 , 31 , 8 , −1, 6 , 43 ,7 , 31 ,

9 , 31 , 8 , −1, 10 , 40 , 11 , 31 ,12 , −1,

68 13 , 43 , 11 , 31 , 12 , −1, 41 , −1,40 , 47 ,

41 , −1, 42 , −1, 41 , 48 , 42 , −1,45 , −1,

70 44 , −1, 14 , 40 , 15 , −1, 40 , 46 ,40 , −1,

16 , −1, 17 , −1, 18 , −1, 19 , −1,20 , −1,

72 21 , −1, 22 , −1, 23 , −1, 24 , −1,25 , −1,

26 , −1, 27 , −174 } ;

76 constant l i s t<Integer> y y r l i n e := {53 , 53 , 55 , 57 , 60 , 62 , 64 , 66 , 68 ,

78 70 , 73 , 76 , 79 , 81 , 84 , 87 , 89 ,93 , 96 ,

99 , 101 , 104 , 106 , 109 , 111 , 113 , 116 ,119 , 121 ,

80 124 , 125 , 126 , 127 , 128 , 129 , 131 , 132 ,134 , 135} ;

82 constant l i s t<String> yytname = {” e r r o r ” , ” $undef ined ” , ”T READ” , ”T WRITE” , ”T ASSIGN” , ”T IF” ,

84 ”T THEN” , ”T ENDIF” , ”T ELSE” , ”T TO” , ”T DO” , ”T END” , ”T WHILE” ,

”T LPAREN” , ”T RPAREN” , ”T IDENT” , ”T INTCONST” , ”T EQ” , ”T LE” , ”T LT” ,

86 ”T GT” , ”T GE” , ”T NE” , ”T ADD” , ”T SUB” , ”T MUL” , ”T DIV” , ”T SEMIC” ,

” $accept ” , ”program” , ” s e r i e s ” , ” statement ” , ” input s tatement ”,

88 ” output statement ” , ” v a r i a b l e l i s t ” , ” ass ignment statement ” ,” c o n d i t i o n a l s t a t e m e n t ” , ” d e f i n i t e l o o p ” , ” w h i l e l o o p ” , ”

exp r e s s i on ” ,90 ”term” , ” element ” , ” comparison ” , ” v a r i a b l e ” , ” constant ” , ”

r e l a t i o n ” ,

Page 175: OMCCp: A MetaModelica Based Parser Generator Applied to ...

E.1. PARSETABLE10.MO 155

” weak operator ” , ” s t r o n g o p e r a t o r ” } ;92

constant l i s t<Integer> yytoknum = {94 256 , 257 , 258 , 259 , 260 , 261 , 262 , 263 , 264 ,

265 , 266 , 267 , 268 , 269 , 270 , 271 , 272 ,273 , 274 ,

96 275 , 276 , 277 , 278 , 279 , 280 , 281 , 282 ,283} ;

98 constant l i s t<Integer> yyr1 = {29 , 30 , 31 , 31 , 32 , 32 , 32 , 32 , 32 ,

100 32 , 33 , 34 , 35 , 35 , 36 , 37 , 37 ,38 , 39 ,

40 , 40 , 41 , 41 , 42 , 42 , 42 , 43 ,44 , 45 ,

102 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 ,48 , 48} ;

104 constant l i s t<Integer> yyr2 = {2 , 1 , 1 , 2 , 2 , 2 , 2 , 1 , 1 ,

106 1 , 2 , 2 , 1 , 2 , 3 , 5 , 7 ,5 , 5 ,

1 , 3 , 1 , 3 , 1 , 1 , 3 , 3 ,1 , 1 ,

108 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 , 1} ;

110 constant l i s t<Integer> yyde fact = {0 , 0 , 0 , 0 , 0 , 0 , 28 , 0 ,

2 , 3 ,112 0 , 0 , 0 , 8 , 9 , 10 , 0 , 11 ,

13 , 12 ,0 , 29 , 0 , 20 , 22 , 0 , 25 , 24 ,

0 , 0 ,114 1 , 4 , 5 , 6 , 7 , 0 , 14 , 0 ,

30 , 31 ,32 , 33 , 34 , 35 , 36 , 37 , 0 , 0 ,

38 , 39 ,116 0 , 0 , 0 , 0 , 15 , 26 , 27 , 21 ,

23 , 0 ,0 , 0 , 16 , 0 , 18 , 19 , 0 , 17

118 } ;

120 constant l i s t<Integer> yydefgoto = {−1, 7 , 8 , 9 , 10 , 11 , 17 , 12 ,

13 , 14 ,122 15 , 22 , 23 , 24 , 25 , 26 , 27 , 46 ,

47 , 50} ;

124constant l i s t<Integer> yypact = {

126 22 , 1 , 1 , 13 , 13 , 13 , −20, 19 ,−20, 22 ,

−8, 5 , 6 , −20, −20, −20, 26 , −20,1 , −20,

128 13 , −20, 46 , −19, −20, 29 , −20, −20,−1, 28 ,

Page 176: OMCCp: A MetaModelica Based Parser Generator Applied to ...

156 APPENDIX E. SAMPLE OUTPUT

−20, −20, −20, −20, −20, 13 , −20, −11,−20, −20,

130 −20, −20, −20, −20, −20, −20, 13 , 13 ,−20, −20,

13 , 22 , 22 , 22 , −13, −20, −13, −19,−20, 7 ,

132 30 , 31 , −20, 22 , −20, −20, 32 , −20} ;

134constant l i s t<Integer> yypgoto = {

136 −20, −20, −6, −20, −20, −20, 3 , −20,−20, −20,

−20, 2 , −3, −9, 44 , 0 , −20, −20,−20, −20

138 } ;

140 constant l i s t<Integer> yytab le = {16 , 18 , 18 , 31 , 55 , 19 , 28 , 48 ,

49 , 16 ,142 52 , 44 , 45 , 44 , 45 , 62 , 63 , 6 ,

18 , 30 ,32 , 36 , 37 , 44 , 45 , 1 , 2 , 20 ,

3 , 6 ,144 21 , 35 , 4 , 33 , 34 , 5 , 51 , 54 ,

6 , 53 ,67 , 58 , 64 , 65 , 57 , 59 , 60 , 61 ,

56 , 29 ,146 0 , 16 , 16 , 16 , 0 , 0 , 0 , 66 ,

0 , 0 ,0 , 0 , 0 , 16 , 38 , 39 , 40 , 41 ,

42 , 43 ,148 44 , 45

} ;150

constant l i s t<Integer> yycheck ={152 0 , 1 , 2 , 9 , 15 , 2 , 4 , 26 ,

27 , 9 ,11 , 24 , 25 , 24 , 25 , 8 , 9 , 16 ,

18 , 0 ,154 28 , 18 , 20 , 24 , 25 , 3 , 4 , 14 ,

6 , 16 ,17 , 5 , 10 , 28 , 28 , 13 , 7 , 35 ,

16 , 11 ,156 8 , 50 , 12 , 12 , 47 , 51 , 52 , 53 ,

46 , 5 ,−1, 51 , 52 , 53 , −1, −1, −1, 63 ,

−1, −1,158 −1, −1, −1, 63 , 18 , 19 , 20 , 21 ,

22 , 23 ,24 , 25

160 } ;

162 constant l i s t<Integer> yystos = {0 , 3 , 4 , 6 , 10 , 13 , 16 , 30 ,

31 , 32 ,164 33 , 34 , 36 , 37 , 38 , 39 , 44 , 35 ,

44 , 35 ,

Page 177: OMCCp: A MetaModelica Based Parser Generator Applied to ...

E.2. PARSECODE10.MO 157

14 , 17 , 40 , 41 , 42 , 43 , 44 , 45 ,40 , 43 ,

166 0 , 31 , 28 , 28 , 28 , 5 , 35 , 40 ,18 , 19 ,

20 , 21 , 22 , 23 , 24 , 25 , 46 , 47 ,26 , 27 ,

168 48 , 7 , 11 , 11 , 40 , 15 , 40 , 41 ,42 , 31 ,

31 , 31 , 8 , 9 , 12 , 12 , 31 , 8170 } ;

172 end ParseTable10 ;

E.2 ParseCode10.mo

Listing E.2: ParseCode10.mo

package ParseCode10 // Generated generated by OMCC v0 . 7 Fr i Apr29 17 : 00 : 58 2011

2import AbsynPAM;

4 import Types ;

6type AstTree = AbsynPAM. Stmt ;

8 type Stmt = AbsynPAM. Stmt ;type IdentLst = AbsynPAM. IdentLst ;

10 type Ident = AbsynPAM. Ident ;type Exp = AbsynPAM. Exp ;

12 type BinOp = AbsynPAM. BinOp ;type RelOp = AbsynPAM. RelOp ;

14constant l i s t<String> lstSemValue2 = {} ;

16constant l i s t<String> lstSemValue = {

18 ” e r r o r ” , ” undetermined ” , ” read ” , ” wr i t e ” , ”:=” ,” i f ” , ” then ” , ” e n d i f ” , ” e l s e ” , ” to ” ,

20 ”do” , ”end” , ” whi l e ” , ” ( ” , ” ) ” ,” I d e n t i t y ” , ” I n t e g e r ” , ”=” , ”<=” , ”<” ,

22 ”>” , ”>=” , ”<>” , ”+” , ”−” ,”∗” , ”/” , ” ; ” , ”” } ;

24

26 uniontype AstStackrecord ASTSTACK

28 l i s t<RelOp> stackRelOp ;l i s t<BinOp> stackBinOp ;

30 l i s t<Exp> stackExp ;l i s t<Ident> s tack Ident ;

32 l i s t<IdentLst> s tack IdentLs t ;l i s t<Stmt> stackStmt ;

34 l i s t<String> s t a c k S t r i n g ;l i s t<Integer> s t a c k I n t e g e r ;

36 end ASTSTACK;

Page 178: OMCCp: A MetaModelica Based Parser Generator Applied to ...

158 APPENDIX E. SAMPLE OUTPUT

record EMPTY end EMPTY;38 end AstStack ;

40 function i n i tAs tS tackinput AstStack astStack ;

42 output AstStack astStack2 ;algorithm

44 astStack2 := ASTSTACK({} ,{} ,{} ,{} ,{} ,{} ,{} ,{} ) ;end i n i tAs tS tack ;

46function getAST ” re tu rn s the AST b u i l t by the par s ing ”

48 input AstStack astStk ”MultiTypedStack used by the par s e r ” ;output AstTree as t ” r e tu rn s the AST in the f i n a l type o f the

t r e e ” ;50 l i s t<Stmt> r e tStk ;

algorithm52 ASTSTACK( stackStmt=retStk ) := astStk ;

a s t : : := re tStk ;54 end getAST ;

56 function actionRedinput Integer act ;

58 input AstStack astStk ;output AstStack astStk2 ;

60 // env v a r i a b l e s// AstStack

62 l i s t<RelOp> skRelOp ;l i s t<BinOp> skBinOp ;

64 l i s t<Exp> skExp ;l i s t<Ident> skIdent ;

66 l i s t<IdentLst> sk IdentLst ;l i s t<Stmt> skStmt ;

68 l i s t<String> skS t r ing ;l i s t<Integer> s k I n t e g e r ;

70

72algorithm

74/∗ ASTSTACK( identStack=idStk , in tStack=inStk , binOpStack=boStk ,

76 relOpStack=roStk , expStack=exStk , identLstStack=i lS tk ,stmtStack=stStk ) := astStk ; ∗/

ASTSTACK( stackRelOp=skRelOp , stackBinOp=skBinOp , stackExp=skExp , s tack Ident=skIdent , s tack IdentLs t=skIdentLst ,stackStmt=skStmt , s t a c k S t r i n g=skStr ing , s t a c k I n t e g e r=s k I n t e g e r ) := astStk ;

78 ( ) := matchcontinue ( act , as tStk )local

80 // l o c a l v a r i a b l e sRelOp vRelOp , v1RelOp , v2RelOp , v3RelOp , v4RelOp , v5RelOp

, v6RelOp , v7RelOp ;82 BinOp vBinOp , v1BinOp , v2BinOp , v3BinOp , v4BinOp , v5BinOp

, v6BinOp , v7BinOp ;Exp vExp , v1Exp , v2Exp , v3Exp , v4Exp , v5Exp , v6Exp , v7Exp

;84 Ident vIdent , v1Ident , v2Ident , v3Ident , v4Ident , v5Ident

, v6Ident , v7Ident ;

Page 179: OMCCp: A MetaModelica Based Parser Generator Applied to ...

E.2. PARSECODE10.MO 159

IdentLst vIdentLst , v1IdentLst , v2IdentLst , v3IdentLst ,v4IdentLst , v5IdentLst , v6IdentLst , v7IdentLst ;

86 Stmt vStmt , v1Stmt , v2Stmt , v3Stmt , v4Stmt , v5Stmt ,v6Stmt , v7Stmt ;

String vStr ing , v1Str ing , v2Str ing , v3Str ing , v4Str ing ,v5Str ing , v6Str ing , v7Str ing ;

88 Integer vInteger , v1Integer , v2Integer , v3Integer ,v4Integer , v5Integer , v6Integer , v7 Intege r ;

90 case (2 , ) // #l i n e 54 ” parse r10 . y”equation

92 // reducev1Stmt : : skStmt = skStmt ;

94 // bu i ldvStmt = ( v1Stmt ) ;

96 // push ResultskStmt= vStmt : : skStmt ;

98then ( ) ;

100case (3 , ) // #l i n e 56 ” parse r10 . y”

102 equation// reduce

104 v1Stmt : : skStmt = skStmt ;// bu i ld

106 vStmt = AbsynPAM.SEQ( ( v1Stmt ) , AbsynPAM. SKIP ( ) ) ;// push Result

108 skStmt= vStmt : : skStmt ;

110 then ( ) ;

112 case (4 , ) // #l i n e 58 ” parse r10 . y”equation

114 // reducev1Stmt : : skStmt = skStmt ;

116 v2Stmt : : skStmt = skStmt ;// bu i ld

118 vStmt = AbsynPAM.SEQ( ( v1Stmt ) , ( v2Stmt ) ) ;// push Result

120 skStmt= vStmt : : skStmt ;

122 then ( ) ;

124 case (5 , ) // #l i n e 61 ” parse r10 . y”equation

126 // reducev1Stmt : : skStmt = skStmt ;

128 v2Str ing : : s kS t r ing = skSt r ing ;// bu i ld

130 vStmt = ( v1Stmt ) ;// push Result

132 skStmt= vStmt : : skStmt ;

134 then ( ) ;

136 case (6 , ) // #l i n e 63 ” parse r10 . y”equation

Page 180: OMCCp: A MetaModelica Based Parser Generator Applied to ...

160 APPENDIX E. SAMPLE OUTPUT

138 // reducev1Stmt : : skStmt = skStmt ;

140 v2Str ing : : s kS t r ing = skSt r ing ;// bu i ld

142 vStmt = ( v1Stmt ) ;// push Result

144 skStmt= vStmt : : skStmt ;

146 then ( ) ;

148 case (7 , ) // #l i n e 65 ” parse r10 . y”equation

150 // reducev1Stmt : : skStmt = skStmt ;

152 v2Str ing : : s kS t r ing = skSt r ing ;// bu i ld

154 vStmt = ( v1Stmt ) ;// push Result

156 skStmt= vStmt : : skStmt ;

158 then ( ) ;

160 case (8 , ) // #l i n e 67 ” parse r10 . y”equation

162 // reducev1Stmt : : skStmt = skStmt ;

164 // bu i ldvStmt = ( v1Stmt ) ;

166 // push ResultskStmt= vStmt : : skStmt ;

168then ( ) ;

170case (9 , ) // #l i n e 69 ” parse r10 . y”

172 equation// reduce

174 v1Stmt : : skStmt = skStmt ;// bu i ld

176 vStmt = ( v1Stmt ) ;// push Result

178 skStmt= vStmt : : skStmt ;

180 then ( ) ;

182 case (10 , ) // #l i n e 71 ” parse r10 . y”equation

184 // reducev1Stmt : : skStmt = skStmt ;

186 // bu i ldvStmt = ( v1Stmt ) ;

188 // push ResultskStmt= vStmt : : skStmt ;

190then ( ) ;

192case (11 , ) // #l i n e 74 ” parse r10 . y”

194 equation

Page 181: OMCCp: A MetaModelica Based Parser Generator Applied to ...

E.2. PARSECODE10.MO 161

// reduce196 v1Str ing : : s kS t r ing = skSt r ing ;

v2IdentLst : : sk IdentLst = skIdentLst ;198 // bu i ld

vStmt = AbsynPAM.READ( ( v2IdentLst ) ) ;200 // push Result

skStmt= vStmt : : skStmt ;202

then ( ) ;204

case (12 , ) // #l i n e 77 ” parse r10 . y”206 equation

// reduce208 v1Str ing : : s kS t r ing = skSt r ing ;

v2IdentLst : : sk IdentLst = skIdentLst ;210 // bu i ld

vStmt = AbsynPAM.WRITE( ( v2IdentLst ) ) ;212 // push Result

skStmt= vStmt : : skStmt ;214

then ( ) ;216

case (13 , ) // #l i n e 80 ” parse r10 . y”218 equation

// reduce220 v1Ident : : sk Ident = skIdent ;

// bu i ld222 vIdentLst = ( v1Ident ) : : { } ;

// push Result224 skIdentLst= vIdentLst : : sk IdentLst ;

226 then ( ) ;

228 case (14 , ) // #l i n e 82 ” parse r10 . y”equation

230 // reducev1Ident : : sk Ident = skIdent ;

232 v2IdentLst : : sk IdentLst = skIdentLst ;// bu i ld

234 vIdentLst = ( v1Ident ) : : ( v2IdentLst ) ;// push Result

236 skIdentLst= vIdentLst : : sk IdentLst ;

238 then ( ) ;

240 case (15 , ) // #l i n e 85 ” parse r10 . y”equation

242 // reducev1Ident : : sk Ident = skIdent ;

244 v2Str ing : : s kS t r ing = skSt r ing ;v3Exp : : skExp = skExp ;

246 // bu i ldvStmt = AbsynPAM. ASSIGN( ( v1Ident ) , ( v3Exp ) ) ;

248 // push ResultskStmt= vStmt : : skStmt ;

250then ( ) ;

Page 182: OMCCp: A MetaModelica Based Parser Generator Applied to ...

162 APPENDIX E. SAMPLE OUTPUT

252case (16 , ) // #l i n e 88 ” parse r10 . y”

254 equation// reduce

256 v1Str ing : : s kS t r ing = skSt r ing ;v2Exp : : skExp = skExp ;

258 v3Str ing : : s kS t r ing = skSt r ing ;v4Stmt : : skStmt = skStmt ;

260 v5Str ing : : s kS t r ing = skSt r ing ;// bu i ld

262 vStmt = AbsynPAM. IF ( ( v2Exp ) , ( v4Stmt ) , AbsynPAM. SKIP( ) ) ;

// push Result264 skStmt= vStmt : : skStmt ;

266 then ( ) ;

268 case (17 , ) // #l i n e 91 ” parse r10 . y”equation

270 // reducev1Str ing : : s kS t r ing = skSt r ing ;

272 v2Exp : : skExp = skExp ;v3Str ing : : s kS t r ing = skSt r ing ;

274 v4Stmt : : skStmt = skStmt ;v5Str ing : : s kS t r ing = skSt r ing ;

276 v6Stmt : : skStmt = skStmt ;v7Str ing : : s kS t r ing = skSt r ing ;

278 // bu i ldvStmt = AbsynPAM. IF ( ( v2Exp ) , ( v4Stmt ) , ( v6Stmt ) ) ;

280 // push ResultskStmt= vStmt : : skStmt ;

282then ( ) ;

284case (18 , ) // #l i n e 94 ” parse r10 . y”

286 equation// reduce

288 v1Str ing : : s kS t r ing = skSt r ing ;v2Exp : : skExp = skExp ;

290 v3Str ing : : s kS t r ing = skSt r ing ;v4Stmt : : skStmt = skStmt ;

292 v5Str ing : : s kS t r ing = skSt r ing ;// bu i ld

294 vStmt = AbsynPAM.TODO( ( v2Exp ) , ( v4Stmt ) ) ;// push Result

296 skStmt= vStmt : : skStmt ;

298 then ( ) ;

300 case (19 , ) // #l i n e 97 ” parse r10 . y”equation

302 // reducev1Str ing : : s kS t r ing = skSt r ing ;

304 v2Exp : : skExp = skExp ;v3Str ing : : s kS t r ing = skSt r ing ;

306 v4Stmt : : skStmt = skStmt ;v5Str ing : : s kS t r ing = skSt r ing ;

Page 183: OMCCp: A MetaModelica Based Parser Generator Applied to ...

E.2. PARSECODE10.MO 163

308 // bu i ldvStmt = AbsynPAM.WHILE( ( v2Exp ) , ( v4Stmt ) ) ;

310 // push ResultskStmt= vStmt : : skStmt ;

312then ( ) ;

314case (20 , ) // #l i n e 100 ” parse r10 . y”

316 equation// reduce

318 v1Exp : : skExp = skExp ;// bu i ld

320 vExp = ( v1Exp ) ;// push Result

322 skExp= vExp : : skExp ;

324 then ( ) ;

326 case (21 , ) // #l i n e 102 ” parse r10 . y”equation

328 // reducev1Exp : : skExp = skExp ;

330 v2BinOp : : skBinOp = skBinOp ;v3Exp : : skExp = skExp ;

332 // bu i ldvExp = AbsynPAM.BINARY( ( v1Exp ) , ( v2BinOp ) , ( v3Exp ) ) ;

334 // push ResultskExp= vExp : : skExp ;

336then ( ) ;

338case (22 , ) // #l i n e 105 ” parse r10 . y”

340 equation// reduce

342 v1Exp : : skExp = skExp ;// bu i ld

344 vExp = ( v1Exp ) ;// push Result

346 skExp= vExp : : skExp ;

348 then ( ) ;

350 case (23 , ) // #l i n e 107 ” parse r10 . y”equation

352 // reducev1Exp : : skExp = skExp ;

354 v2BinOp : : skBinOp = skBinOp ;v3Exp : : skExp = skExp ;

356 // bu i ldvExp = AbsynPAM.BINARY( ( v1Exp ) , ( v2BinOp ) , ( v3Exp ) ) ;

358 // push ResultskExp= vExp : : skExp ;

360then ( ) ;

362case (24 , ) // #l i n e 110 ” parse r10 . y”

364 equation

Page 184: OMCCp: A MetaModelica Based Parser Generator Applied to ...

164 APPENDIX E. SAMPLE OUTPUT

// reduce366 v1Intege r : : s k I n t e g e r = s k I n t e g e r ;

// bu i ld368 vExp = AbsynPAM. INT( ( v1 Intege r ) ) ;

// push Result370 skExp= vExp : : skExp ;

372 then ( ) ;

374 case (25 , ) // #l i n e 112 ” parse r10 . y”equation

376 // reducev1Ident : : sk Ident = skIdent ;

378 // bu i ldvExp = AbsynPAM.IDENT( ( v1Ident ) ) ;

380 // push ResultskExp= vExp : : skExp ;

382then ( ) ;

384case (26 , ) // #l i n e 114 ” parse r10 . y”

386 equation// reduce

388 v1Str ing : : s kS t r ing = skSt r ing ;v2Exp : : skExp = skExp ;

390 v3Str ing : : s kS t r ing = skSt r ing ;// bu i ld

392 vExp = ( v2Exp ) ;// push Result

394 skExp= vExp : : skExp ;

396 then ( ) ;

398 case (27 , ) // #l i n e 117 ” parse r10 . y”equation

400 // reducev1Exp : : skExp = skExp ;

402 v2RelOp : : skRelOp = skRelOp ;v3Exp : : skExp = skExp ;

404 // bu i ldvExp = AbsynPAM.RELATION( ( v1Exp ) , ( v2RelOp ) , ( v3Exp ) )

;406 // push Result

skExp= vExp : : skExp ;408

then ( ) ;410

case (28 , ) // #l i n e 120 ” parse r10 . y”412 equation

// reduce414 v1Str ing : : s kS t r ing = skSt r ing ;

// bu i ld416 vIdent = ( v1Str ing ) ;

// push Result418 skIdent= vIdent : : sk Ident ;

420 then ( ) ;

Page 185: OMCCp: A MetaModelica Based Parser Generator Applied to ...

E.2. PARSECODE10.MO 165

422 case (29 , ) // #l i n e 122 ” parse r10 . y”equation

424 // reducev1Str ing : : s kS t r ing = skSt r ing ;

426 // bu i ldv Int ege r = ( s t r i n g I n t ( v1Str ing ) ) ;

428 // push Results k I n t e g e r= vIntege r : : s k I n t e g e r ;

430then ( ) ;

432case (30 , ) // #l i n e 124 ” parse r10 . y”

434 equation// reduce

436 v1Str ing : : s kS t r ing = skSt r ing ;// bu i ld

438 vRelOp = AbsynPAM.EQ( ) ;// push Result

440 skRelOp= vRelOp : : skRelOp ;

442 then ( ) ;

444 case (31 , ) // #l i n e 125 ” parse r10 . y”equation

446 // reducev1Str ing : : s kS t r ing = skSt r ing ;

448 // bu i ldvRelOp = AbsynPAM.LE( ) ;

450 // push ResultskRelOp= vRelOp : : skRelOp ;

452then ( ) ;

454case (32 , ) // #l i n e 126 ” parse r10 . y”

456 equation// reduce

458 v1Str ing : : s kS t r ing = skSt r ing ;// bu i ld

460 vRelOp = AbsynPAM.LT( ) ;// push Result

462 skRelOp= vRelOp : : skRelOp ;

464 then ( ) ;

466 case (33 , ) // #l i n e 127 ” parse r10 . y”equation

468 // reducev1Str ing : : s kS t r ing = skSt r ing ;

470 // bu i ldvRelOp = AbsynPAM.GT( ) ;

472 // push ResultskRelOp= vRelOp : : skRelOp ;

474then ( ) ;

476case (34 , ) // #l i n e 128 ” parse r10 . y”

Page 186: OMCCp: A MetaModelica Based Parser Generator Applied to ...

166 APPENDIX E. SAMPLE OUTPUT

478 equation// reduce

480 v1Str ing : : s kS t r ing = skSt r ing ;// bu i ld

482 vRelOp = AbsynPAM.GE( ) ;// push Result

484 skRelOp= vRelOp : : skRelOp ;

486 then ( ) ;

488 case (35 , ) // #l i n e 129 ” parse r10 . y”equation

490 // reducev1Str ing : : s kS t r ing = skSt r ing ;

492 // bu i ldvRelOp = AbsynPAM.NE( ) ;

494 // push ResultskRelOp= vRelOp : : skRelOp ;

496then ( ) ;

498case (36 , ) // #l i n e 131 ” parse r10 . y”

500 equation// reduce

502 v1Str ing : : s kS t r ing = skSt r ing ;// bu i ld

504 vBinOp = AbsynPAM.ADD( ) ;// push Result

506 skBinOp= vBinOp : : skBinOp ;

508 then ( ) ;

510 case (37 , ) // #l i n e 132 ” parse r10 . y”equation

512 // reducev1Str ing : : s kS t r ing = skSt r ing ;

514 // bu i ldvBinOp = AbsynPAM.SUB( ) ;

516 // push ResultskBinOp= vBinOp : : skBinOp ;

518then ( ) ;

520case (38 , ) // #l i n e 134 ” parse r10 . y”

522 equation// reduce

524 v1Str ing : : s kS t r ing = skSt r ing ;// bu i ld

526 vBinOp = AbsynPAM.MUL( ) ;// push Result

528 skBinOp= vBinOp : : skBinOp ;

530 then ( ) ;

532 case (39 , ) // #l i n e 135 ” parse r10 . y”equation

534 // reduce

Page 187: OMCCp: A MetaModelica Based Parser Generator Applied to ...

E.2. PARSECODE10.MO 167

v1Str ing : : s kS t r ing = skSt r ing ;536 // bu i ld

vBinOp = AbsynPAM. DIV( ) ;538 // push Result

skBinOp= vBinOp : : skBinOp ;540

then ( ) ;542

case ( , )544 equation

print ( ”FAIL : I l e g a l a c t i on ” ) ;546 //lAST = i n t S t r i n g ( act ) ;

then ( ) ;548 end matchcontinue ;

a s tStk2 := ASTSTACK( skRelOp , skBinOp , skExp , skIdent , skIdentLst, skStmt , skStr ing , s k I n t e g e r ) ;

550 /∗ astStk2 := ASTSTACK( idStk , inStk , boStk , roStk , exStk , i l S t k ,s tStk ) ; ∗/

552 end actionRed ;

554 function pushinput AstStack astStk ;

556 input String inVal ;output AstStack astStk2 ;

558 // AstStackl i s t<RelOp> skRelOp ;

560 l i s t<BinOp> skBinOp ;l i s t<Exp> skExp ;

562 l i s t<Ident> skIdent ;l i s t<IdentLst> sk IdentLst ;

564 l i s t<Stmt> skStmt ;l i s t<String> skS t r ing ;

566 l i s t<Integer> s k I n t e g e r ;

568 algorithmASTSTACK( stackRelOp=skRelOp , stackBinOp=skBinOp , stackExp=skExp ,

s tack Ident=skIdent , s tack IdentLs t=skIdentLst , stackStmt=skStmt , s t a c k S t r i n g=skStr ing , s t a c k I n t e g e r=s k I n t e g e r ) :=astStk ;

570 skSt r ing := inVal : : s kS t r ing ;astStk2 := ASTSTACK( skRelOp , skBinOp , skExp , skIdent , skIdentLst ,

skStmt , skStr ing , s k I n t e g e r ) ;572 end push ;

574

576 function printAST ” p r i n t the AST b u i l t by the par s ing ”input AstStack astStk ”MultiTypedStack used by the par s e r ” ;

578 output AstTree as t ” r e tu rn s the AST in the f i n a l type o f thet r e e ” ;

l i s t<AbsynPAM. Stmt> r e tStk ;580 algorithm

ASTSTACK( stackStmt=retStk ) := astStk ;582 printAny ( as t ) ;

a s t : : := re tStk ;584 end printAST ;

Page 188: OMCCp: A MetaModelica Based Parser Generator Applied to ...

168 APPENDIX E. SAMPLE OUTPUT

586 function getSemValue ” r e t r i e v e s semval from tokens ”input Integer tokenId ;

588 output String tokenSemValue ” r e tu rn s semantic va lue o f thetoken ” ;

array<String> va lue s ;590 algorithm

va lue s := l i s t A r r a y ( lstSemValue ) ;592 tokenSemValue := va lue s [ tokenId ] ;

end getSemValue ;594

596 end ParseCode10 ;

E.3 Token10.mo

Listing E.3: Token10.mo

package Token10 // generated by OMCC v0 . 7 generated by OMCC v0. 7 Fr i Apr 29 17 : 00 : 58 2011

2constant Integer T READ = 258 ;

4 constant Integer T WRITE = 259 ;constant Integer T ASSIGN = 260 ;

6 constant Integer T IF = 261 ;constant Integer T THEN = 262 ;

8 constant Integer T ENDIF = 263 ;constant Integer T ELSE = 264 ;

10 constant Integer T TO = 265 ;constant Integer T DO = 266 ;

12 constant Integer T END = 267 ;constant Integer T WHILE = 268 ;

14 constant Integer T LPAREN = 269 ;constant Integer T RPAREN = 270 ;

16 constant Integer T IDENT = 271 ;constant Integer T INTCONST = 272 ;

18 constant Integer T EQ = 273 ;constant Integer T LE = 274 ;

20 constant Integer T LT = 275 ;constant Integer T GT = 276 ;

22 constant Integer T GE = 277 ;constant Integer T NE = 278 ;

24 constant Integer T ADD = 279 ;constant Integer T SUB = 280 ;

26 constant Integer T MUL = 281 ;constant Integer T DIV = 282 ;

28 constant Integer T SEMIC = 283 ;end Token10 ;

E.4 LexTable10.mo

Page 189: OMCCp: A MetaModelica Based Parser Generator Applied to ...

E.4. LEXTABLE10.MO 169

Listing E.4: LexTable10.mo

1 package LexTable10 // generated by OMCC v0 . 7 Fr i Apr 2917 : 00 : 58 2011

3constant Integer y y l i m i t := 65 ;

5constant Integer y y f i n i s h := 76 ;

7constant l i s t<Integer> y y a c c l i s t := {

9 33 , 32 , 1 , 32 , 18 , 32 , 19 , 32 , 16 , 32 ,14 , 32 , 15 , 32 , 17 , 32 , 12 , 32 , 32 , 26 ,

11 32 , 20 , 32 , 22 , 32 , 25 , 32 , 11 , 32 , 11 ,32 , 11 , 32 , 11 , 32 , 11 , 32 , 11 , 32 , 11 ,

13 32 , 30 , 32 , 31 , 32 , 30 , 32 , 30 , 32 , 1 ,27 , 12 , 13 , 21 , 23 , 24 , 11 , 3 , 11 , 11 ,

15 11 , 7 , 11 , 11 , 11 , 11 , 11 , 28 , 29 , 11 ,5 , 11 , 11 , 11 , 11 , 11 , 4 , 11 , 11 , 8 ,

17 11 , 9 , 11 , 11 , 11 , 6 , 11 , 2 , 11 , 10 ,11

19} ;

21constant l i s t<Integer> yy accept := {

23 1 , 1 , 1 , 1 , 1 , 2 , 3 , 5 , 7 , 9 ,11 , 13 , 15 , 17 , 19 , 20 , 22 , 24 , 26 , 28 ,

25 30 , 32 , 34 , 36 , 38 , 40 , 42 , 44 , 46 , 48 ,50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 60 ,

27 61 , 62 , 64 , 65 , 66 , 67 , 68 , 69 , 70 , 71 ,73 , 74 , 75 , 76 , 77 , 79 , 80 , 82 , 84 , 85 ,

29 86 , 88 , 90 , 92 , 92} ;

31constant l i s t<Integer> yy ec := {

33 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 3 ,1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,

35 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 , 2 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 4 ,

37 5 , 6 , 7 , 1 , 8 , 1 , 9 , 10 , 10 , 10 ,10 , 10 , 10 , 10 , 10 , 10 , 10 , 11 , 12 , 13 ,

39 14 , 15 , 1 , 1 , 16 , 16 , 16 , 16 , 16 , 16 ,16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 ,

41 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 ,1 , 1 , 1 , 1 , 1 , 1 , 17 , 16 , 16 , 18 ,

4319 , 20 , 16 , 21 , 22 , 16 , 16 , 23 , 16 , 24 ,

45 25 , 16 , 16 , 26 , 27 , 28 , 16 , 16 , 29 , 16 ,16 , 16 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,

47 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,

49 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,

51 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,

53 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,

Page 190: OMCCp: A MetaModelica Based Parser Generator Applied to ...

170 APPENDIX E. SAMPLE OUTPUT

55 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,

57 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,

59 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 , 1 , 1 , 1 , 1

61 } ;

63 constant l i s t<Integer> yy meta := {1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2 ,

65 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2

67 } ;

69 constant l i s t<Integer> yy base := {0 , 0 , 27 , 28 , 75 , 76 , 36 , 76 , 76 , 76 ,

71 76 , 76 , 68 , 63 , 58 , 76 , 26 , 76 , 57 , 0 ,45 , 19 , 49 , 49 , 46 , 23 , 76 , 76 , 57 , 59 ,

73 43 , 76 , 54 , 76 , 76 , 76 , 76 , 0 , 0 , 36 ,44 , 0 , 44 , 41 , 37 , 36 , 76 , 76 , 38 , 34 ,

75 37 , 30 , 30 , 24 , 0 , 28 , 0 , 0 , 28 , 16 ,0 , 0 , 0 , 76 , 49 , 30

77 } ;

79 constant l i s t<Integer> yy de f := {64 , 1 , 65 , 65 , 64 , 64 , 64 , 64 , 64 , 64 ,

81 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 66 ,66 , 66 , 66 , 66 , 66 , 66 , 64 , 64 , 64 , 64 ,

83 64 , 64 , 64 , 64 , 64 , 64 , 64 , 66 , 66 , 66 ,66 , 66 , 66 , 66 , 66 , 66 , 64 , 64 , 66 , 66 ,

85 66 , 66 , 66 , 66 , 66 , 66 , 66 , 66 , 66 , 66 ,66 , 66 , 66 , 0 , 64 , 64

87 } ;

89 constant l i s t<Integer> yy nxt := {6 , 7 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 ,

91 15 , 16 , 17 , 18 , 19 , 20 , 20 , 21 , 22 , 20 ,20 , 23 , 20 , 20 , 20 , 24 , 20 , 25 , 26 , 28 ,

93 28 , 38 , 29 , 29 , 63 , 30 , 30 , 31 , 31 , 35 ,36 , 40 , 41 , 45 , 31 , 31 , 62 , 61 , 46 , 27 ,

95 27 , 60 , 59 , 58 , 57 , 56 , 55 , 54 , 53 , 52 ,51 , 50 , 49 , 33 , 48 , 47 , 44 , 43 , 42 , 39 ,

97 37 , 34 , 33 , 32 , 64 , 5 , 64 , 64 , 64 , 64 ,64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 ,

99 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 ,

101 64 , 64 , 64 , 64 , 64} ;

103constant l i s t<Integer> yy chk := {

105 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,

107 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 3 ,4 , 66 , 3 , 4 , 60 , 3 , 4 , 7 , 7 , 17 ,

109 17 , 22 , 22 , 26 , 31 , 31 , 59 , 56 , 26 , 65 ,65 , 54 , 53 , 52 , 51 , 50 , 49 , 46 , 45 , 44 ,

111 43 , 41 , 40 , 33 , 30 , 29 , 25 , 24 , 23 , 21 ,

Page 191: OMCCp: A MetaModelica Based Parser Generator Applied to ...

E.5. LEXERCODE10.MO 171

19 , 15 , 14 , 13 , 5 , 64 , 64 , 64 , 64 , 64 ,113 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 ,

64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 ,115

64 , 64 , 64 , 64 , 64117 } ;

119 end LexTable10 ;

E.5 LexerCode10.mo

Listing E.5: LexerCode10.mo

1 package LexerCode10 // Generated generated by OMCC v0 . 7 Fr i Apr29 17 : 00 : 58 2011

3 /∗Template f o r Lexer Code

5 r e p l a c e keywords :%LexerCode

7 %time%Token

9 %Lexer%ParseTable

11 %constant%nameSpan

13 %f u n c t i o n s%caseAct ion

15 ∗/import Types ;

17 import Token10 ;import Lexer10 ;

19 import ParseTable10 ;

21

23 function ac t i oninput Integer act ;

25 input Lexer10 . Env env ;output Option<Types . Token> token ;

27 output Lexer10 . Env env2 ;Integer mm startSt , mm currSt , mm pos , mm sPos , mm ePos ,

mm linenr , mm fl inenr ;29 l i s t<Integer> bu f f e r , bkBuffer , tb ;

Types . In f o i n f o ;31 array<String> tokName ;

String sToken , f i leNm ;33 Integer nameSpan , act2 ;

Boolean debug ;35 algorithm

Lexer10 .ENV( s t a r t S t=mm startSt , cur rSt=mm currSt , pos=mm pos ,sPos=mm sPos , ePos=mm ePos ,

37 l i n e n r=mm linenr , bu f f=bu f f e r , bkBuf=bkBuffer , i sDebugging=debug , f i leName=fi leNm ) := env ;

Page 192: OMCCp: A MetaModelica Based Parser Generator Applied to ...

172 APPENDIX E. SAMPLE OUTPUT

b u f f e r := l i s t R e v e r s e ( b u f f e r ) ;39 tb := b u f f e r ;

sToken := Lexer10 . p r i n t B u f f e r ( tb , ”” ) ;41 tokName := l i s t A r r a y ( ParseTable10 . yytname ) ;

nameSpan := 255 ;43 tb := b u f f e r ;

// ( tb , mm fl inenr ) := Lexer10 . l ineUpd ( tb , mm fl inenr ) ;45 i n f o := Lexer10 . g e t I n f o ( tb , mm sPos , mm linenr , f i leNm ) ;

// i n f o := Types . INFO( fileNm , f a l s e , mm linenr , mm sPos ,mm flinenr , mm pos) ;

47 // p r i n t (”\n” + i n t S t r i n g ( act ) + ” : ” ) ;act2 := act ;

49( token ) := matchcontinue ( act )

51 localTypes . Token tok ;

53 case (1 ) // #l i n e 35 ” l e x e r 1 0 . l ”then (NONE( ) ) ;

55 case (2 ) // #l i n e 36 ” l e x e r 1 0 . l ”equation

57 act2 = Token10 .T WHILE;tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;59 then (SOME( tok ) ) ;

case (3 ) // #l i n e 37 ” l e x e r 1 0 . l ”61 equation

act2 = Token10 .T DO;63 tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;then (SOME( tok ) ) ;

65 case (4 ) // #l i n e 38 ” l e x e r 1 0 . l ”equation

67 act2 = Token10 . T ELSE ;tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;69 then (SOME( tok ) ) ;

case (5 ) // #l i n e 39 ” l e x e r 1 0 . l ”71 equation

act2 = Token10 .T END;73 tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;then (SOME( tok ) ) ;

75 case (6 ) // #l i n e 40 ” l e x e r 1 0 . l ”equation

77 act2 = Token10 . T ENDIF ;tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;79 then (SOME( tok ) ) ;

case (7 ) // #l i n e 41 ” l e x e r 1 0 . l ”81 equation

act2 = Token10 . T IF ;83 tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;then (SOME( tok ) ) ;

85 case (8 ) // #l i n e 42 ” l e x e r 1 0 . l ”equation

87 act2 = Token10 .T READ;

Page 193: OMCCp: A MetaModelica Based Parser Generator Applied to ...

E.5. LEXERCODE10.MO 173

tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,i n f o ) ;

89 then (SOME( tok ) ) ;case (9 ) // #l i n e 43 ” l e x e r 1 0 . l ”

91 equationact2 = Token10 .T THEN;

93 tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,i n f o ) ;

then (SOME( tok ) ) ;95 case (10) // #l i n e 44 ” l e x e r 1 0 . l ”

equation97 act2 = Token10 .T WRITE;

tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,i n f o ) ;

99 then (SOME( tok ) ) ;case (11) // #l i n e 45 ” l e x e r 1 0 . l ”

101 equationact2 = Token10 . T IDENT ;

103 tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,i n f o ) ;

then (SOME( tok ) ) ;105 case (12) // #l i n e 46 ” l e x e r 1 0 . l ”

equation107 act2 = Token10 .T INTCONST;

tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,i n f o ) ;

109 then (SOME( tok ) ) ;case (13) // #l i n e 47 ” l e x e r 1 0 . l ”

111 equationact2 = Token10 . T ASSIGN ;

113 tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,i n f o ) ;

then (SOME( tok ) ) ;115 case (14) // #l i n e 48 ” l e x e r 1 0 . l ”

equation117 act2 = Token10 .T ADD;

tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,i n f o ) ;

119 then (SOME( tok ) ) ;case (15) // #l i n e 49 ” l e x e r 1 0 . l ”

121 equationact2 = Token10 . T SUB ;

123 tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,i n f o ) ;

then (SOME( tok ) ) ;125 case (16) // #l i n e 50 ” l e x e r 1 0 . l ”

equation127 act2 = Token10 .T MUL;

tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,i n f o ) ;

129 then (SOME( tok ) ) ;case (17) // #l i n e 51 ” l e x e r 1 0 . l ”

131 equationact2 = Token10 . T DIV ;

133 tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,i n f o ) ;

then (SOME( tok ) ) ;

Page 194: OMCCp: A MetaModelica Based Parser Generator Applied to ...

174 APPENDIX E. SAMPLE OUTPUT

135 case (18) // #l i n e 52 ” l e x e r 1 0 . l ”equation

137 act2 = Token10 .T LPAREN;tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;139 then (SOME( tok ) ) ;

case (19) // #l i n e 53 ” l e x e r 1 0 . l ”141 equation

act2 = Token10 .T RPAREN;143 tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;then (SOME( tok ) ) ;

145 case (20) // #l i n e 54 ” l e x e r 1 0 . l ”equation

147 act2 = Token10 . T LT ;tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;149 then (SOME( tok ) ) ;

case (21) // #l i n e 55 ” l e x e r 1 0 . l ”151 equation

act2 = Token10 . T LE ;153 tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;then (SOME( tok ) ) ;

155 case (22) // #l i n e 56 ” l e x e r 1 0 . l ”equation

157 act2 = Token10 .T EQ;tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;159 then (SOME( tok ) ) ;

case (23) // #l i n e 57 ” l e x e r 1 0 . l ”161 equation

act2 = Token10 . T NE ;163 tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;then (SOME( tok ) ) ;

165 case (24) // #l i n e 58 ” l e x e r 1 0 . l ”equation

167 act2 = Token10 .T GE;tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;169 then (SOME( tok ) ) ;

case (25) // #l i n e 59 ” l e x e r 1 0 . l ”171 equation

act2 = Token10 .T GT;173 tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;then (SOME( tok ) ) ;

175 case (26) // #l i n e 60 ” l e x e r 1 0 . l ”equation

177 act2 = Token10 . T SEMIC ;tok = Types .TOKEN(tokName [ act2−nameSpan ] , act2 , bu f f e r ,

i n f o ) ;179 then (SOME( tok ) ) ;

case (27) // #l i n e 63 ” l e x e r 1 0 . l ”181 equation

mm startSt = 3 ;

Page 195: OMCCp: A MetaModelica Based Parser Generator Applied to ...

E.5. LEXERCODE10.MO 175

183 then (NONE( ) ) ;case (28) // #l i n e 68 ” l e x e r 1 0 . l ”

185 equationmm startSt = 1 ;

187 then (NONE( ) ) ;case (29) // #l i n e 69 ” l e x e r 1 0 . l ”

189 then (NONE( ) ) ;case (30) // #l i n e 70 ” l e x e r 1 0 . l ”

191 then (NONE( ) ) ;case (31) // #l i n e 71 ” l e x e r 1 0 . l ”

193 then (NONE( ) ) ;case (32) // #l i n e 78 ” l e x e r 1 0 . l ”

195 then (NONE( ) ) ;

197 case ( )equation

199 // p r i n t ( ” [ ente r e l s e ] ” ) ;print ( ”ERROR TOKEN NOT FOUND: [ ’ ” + sToken + ” ’ TK: ” +

intString ( act ) + ” , ” + tokName [ act2 ] + ” ] ” ) ;201 tok = Types .TOKEN(tokName [ act2 ] , act , bu f f e r , i n f o ) ;

then (NONE( ) ) ;203 end matchcontinue ;

env2 := Lexer10 .ENV( mm startSt , mm startSt , mm pos , mm sPos ,mm sPos , mm linenr ,{} , bkBuffer ,{mm startSt } , debug , f i leNm) ;

205 i f ( debug==true ) thenprint ( ”\n [TOKEN: ’ ” + sToken + ” ’ ( ”+ intString (mm sPos ) +

” : ” + intString ( mm linenr ) +” ) id : ” + intString ( act2) + ” ] ” ) ;

207 end i f ;end ac t i on ;

209

211end LexerCode10 ;

Page 196: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Appendix F

Modelica Grammar

F.1 lexerModelica.l

Listing F.1: lexerModelica.l

%{2

%}4

%x c comment6 %x c l inecomment

%x c s t r i n g8

whitespace [ \ t \n]+10 l e t t e r [ a−zA−Z ]

wi ld [ ]12 ident ({ l e t t e r } |{ wild }) ({ l e t t e r } |{ d i g i t } |{ wild }) ∗

d i g i t [0−9]14 d i g i t s { d i g i t}+

exponent ( [ e ] | [ E ] ) ( [ + ] | [ − ] ) ?{ d i g i t s }16 r e a l { d i g i t s } [ \ . ] ( { d i g i t s }) ?({ exponent }) ?

r e a l 2 { d i g i t s }{ exponent}18 e n d i f ”end”{whitespace }” i f ”

endfor ”end”{whitespace }” f o r ”20 endwhi le ”end”{whitespace }” whi l e ”

endwhen ”end”{whitespace }”when”22 endmatch ”end”{whitespace }”match”

endmatchcontinue ”end”{whitespace }” matchcontinue ”24 endident ”end”{whitespace }{ i dent }

26 /∗ Lex s t y l e l e x i c a l syntax o f tokens in the MODELICA language∗/

28

30 %%

32 {whitespace } ;

176

Page 197: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.1. LEXERMODELICA.L 177

{ r e a l } return UNSIGNED REAL;34 { r e a l 2 } return UNSIGNED REAL;

{ e n d i f } return ENDIF;36 { endfor } return ENDFOR;

{ endwhi le } return ENDWHILE;38 {endwhen} return ENDWHEN;

{ endmatchcontinue} return ENDMATCHCONTINUE;40 {endmatch} return ENDMATCH;

{ endident } return ENDCLASS;42 ” a lgor i thm ” return T ALGORITHM;

”and” return T AND;44 ” annotat ion ” return T ANNOTATION;

” block ” return BLOCK;46 ” c l a s s ” return CLASS;

” connect ” return CONNECT;48 ” connector ” return CONNECTOR;

” constant ” return CONSTANT;50 ” d i s c r e t e ” return DISCRETE;

” der ” return DER;52 ” d e f i n e u n i t ” return DEFINEUNIT;

” each ” return EACH;54 ” e l s e ” return ELSE;

” e l s e i f ” return ELSEIF ;56 ” elsewhen ” return ELSEWHEN;

”end” return T END;58 ” enumeration ” return ENUMERATION;

” equat ion ” return EQUATION;60 ” encapsu lated ” return ENCAPSULATED;

” expandable ” return EXPANDABLE;62 ” extends ” return EXTENDS;

” const ra inedby ” return CONSTRAINEDBY;64 ” e x t e r n a l ” return EXTERNAL;

” f a l s e ” return T FALSE ;66 ” f i n a l ” return FINAL ;

” f low ” return FLOW;68 ” f o r ” return FOR;

” func t i on ” return FUNCTION;70 ” i f ” return IF ;

” import ” return IMPORT;72 ” in ” return T IN ;

” i n i t i a l ” return INITIAL ;74 ” inner ” return INNER;

” input ” return T INPUT ;76 ” loop ” return LOOP;

”model” return MODEL;78 ” not ” return T NOT;

” outer ” return T OUTER;80 ” operator ” return OPERATOR;

” over load ” return OVERLOAD;82 ” or ” return T OR;

” output ” return T OUTPUT;84 ” package ” return T PACKAGE;

” parameter ” return PARAMETER;86 ” p a r t i a l ” return PARTIAL;

” protec ted ” return PROTECTED;88 ” pub l i c ” return PUBLIC;

” record ” return RECORD;

Page 198: OMCCp: A MetaModelica Based Parser Generator Applied to ...

178 APPENDIX F. MODELICA GRAMMAR

90 ” r e d e c l a r e ” return REDECLARE;” r e p l a c e a b l e ” return REPLACEABLE;

92 ” r e s u l t s ” return RESULTS;” then ” return THEN;

94 ” true ” return T TRUE;” type ” return TYPE;

96 ” u n s i g n e d r e a l ” return UNSIGNED REAL;”when” return WHEN;

98 ” whi l e ” return WHILE;” with in ” return WITHIN;

100 ” re turn ” return RETURN;” break ” return BREAK;

102” ( ” return LPAR;

104 ” ) ” return RPAR;” [ ” return LBRACK;

106 ” ] ” return RBRACK;”{” return LBRACE;

108 ”}” return RBRACE;”==” return EQEQ;

110 ”=” return EQUALS;” , ” return COMMA;

112 ”:=” return ASSIGN ;” : : ” return COLONCOLON;

114 ” : ” return COLON;” ; ” return SEMICOLON;

116”Code” return CODE;

118 ”$Code” return CODE;”$TypeName” return CODE NAME;

120 ”$Exp” return CODE EXP;”$Var” return CODE VAR;

122” pure ” return PURE;

124 ” impure” return IMPURE;

126 ”.+” return PLUS EW;”.−” return MINUS EW;

128 ” .∗ ” return STAR EW;” . / ” return SLASH EW;

130 ” . ˆ ” return POWEREW;

132 ”∗” return STAR;”−” return MINUS;

134 ”+” return PLUS;”<=” return LESSEQ;

136 ”<>” return LESSGT;”<” return LESS ;

138 ”>” return GREATER;”>=” return GREATEREQ;

140”ˆ” return POWER;

142 ”/” return SLASH;

144 ” as ” return AS;” case ” return CASE;

146 ” e q u a l i t y ” return EQUALITY;

Page 199: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.1. LEXERMODELICA.L 179

” f a i l u r e ” return FAILURE;148 ”guard” return GUARD;

” l o c a l ” return LOCAL;150 ”match” return MATCH;

” matchcontinue ” return MATCHCONTINUE;152 ” uniontype ” return UNIONTYPE;

” ” return ALLWILD;154 ” ” return WILD;

” subtypeof ” return SUBTYPEOF;156 ”\%” return MOD;

158 ” stream ” return STREAM;

160 ” \ . ” return DOT;

162 %” [ \ ” ] [ ˆ \ ” ] ∗ [ \ ” ] ” return STRING;

164 { i d ent } return IDENT;{ d i g i t s } return UNSIGNED INTEGER;

166”\”” {

168 BEGIN( c s t r i n g ) keepBuf fe r ;}

170 <c s t r i n g >{

172 ”\\\”” { keepBuf fe r ; }”\”” { BEGIN( INITIAL ) return STRING; }

174 [ˆ\n ] { keepBuf fe r ; } ;\n { keepBuf fe r ; } ;

176 <<EOF>> {yyer ro r ( ”Unterminated s t r i n g ” ) ;

178 yyterminate ( ) ;}

180 }

182 ”/\∗” {BEGIN( c comment ) ;

184 }<c comment>

186 {”\∗/” { BEGIN( INITIAL ) ; }

188 ”/\∗” { yyer ro r ( ” Susp i c i ou s comment” ) ; }[ ˆ\n ] ;

190 \n ;<<EOF>> {

192 yyer ro r ( ”Unterminated comment” ) ;yyterminate ( ) ;

194 }}

196”//” {

198 BEGIN( c l inecomment ) keepBuf fer ;}

200<c l inecomment>

202 {\n { BEGIN( INITIAL ) ; }

Page 200: OMCCp: A MetaModelica Based Parser Generator Applied to ...

180 APPENDIX F. MODELICA GRAMMAR

204 [ˆ\n ] ;}

206

208%%

F.2 parserModelica.y

Listing F.2: parserModelica.y

1 %{import Absyn ;

3 /∗ Type Dec l a ra t i on s ∗/type AstTree = Absyn . Program ;

5 type Token = OMCCTypes . Token ;type Program = Absyn . Program ;

7 type Within = Absyn . Within ;type l s t C l a s s = l i s t<Absyn . Class >;

9 type Class = Absyn . Class ;type Ident = Absyn . Ident ;

11 type Path = Absyn . Path ;type ClassDef = Absyn . ClassDef ;

13 type ClassPart = Absyn . ClassPart ;type ClassPart s = l i s t<ClassPart >;

15 type Import = Absyn . Import ;type ElementItem = Absyn . ElementItem ;

17 type ElementItems = l i s t<Absyn . ElementItem >;type Element = Absyn . Element ;

19 type ElementSpec = Absyn . ElementSpec ;type ElementAttr ibutes = Absyn . ElementAttr ibutes ;

21 type Comment = Absyn . Comment ;type D i r e c t i on = Absyn . D i r e c t i on ;

23 type Exp = Absyn . Exp ;type Exps = l i s t<Exp>;

25 type Matrix = l i s t<l i s t<Exp>>;type Subsc r ip t = Absyn . Subsc r ip t ;

27 type ArrayDim = l i s t<Subscr ipt >;type Operator = Absyn . Operator ;

29 type Case = Absyn . Case ;type Cases = l i s t<Case>;

31 type MatchType = Absyn . MatchType ;type R e s t r i c t i o n = Absyn . R e s t r i c t i o n ;

33 type InnerOuter = Absyn . InnerOuter ;type ComponentRef = Absyn . ComponentRef ;

35 type V a r i a b i l i t y = Absyn . V a r i a b i l i t y ;type RedeclareKeywords = Absyn . RedeclareKeywords ;

37 type NamedArg=Absyn . NamedArg ;type TypeSpec=Absyn . TypeSpec ;

39 type TypeSpecs=l i s t<TypeSpec>;type ComponentItem=Absyn . ComponentItem ;

41 type ComponentItems=l i s t<ComponentItem>;type Component=Absyn . Component ;

43 type EquationItem = Absyn . EquationItem ;

Page 201: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.2. PARSERMODELICA.Y 181

type EquationItems = l i s t<EquationItem >;45 type Equation = Absyn . Equation ;

type E l s e i f = tuple<Exp , l i s t<EquationItem>>;47 type E l s e i f s = l i s t<E l s e i f >;

type F o r I t e r a t o r= Absyn . F o r I t e r a t o r ;49 type F o r I t e r a t o r s = l i s t<For I t e ra to r >;

type Elsewhen = tuple<Exp , l i s t<EquationItem>>;51 type Elsewhens = l i s t<Elsewhen >;

type FunctionArgs = Absyn . FunctionArgs ;53 type NamedArgs = l i s t<NamedArg>;

type AlgorithmItem = Absyn . AlgorithmItem ;55 type AlgorithmItems = l i s t<AlgorithmItem >;

type Algorithm = Absyn . Algorithm ;57 type A l g E l s e i f = tuple<Exp , l i s t<AlgorithmItem>>;

type A l g E l s e i f s = l i s t<AlgE l s e i f >;59 type AlgElsewhen = tuple<Exp , l i s t<AlgorithmItem>>;

type AlgElsewhens = l i s t<AlgElsewhen >;61 type ExpElse i f = tuple<Exp , Exp>;

type ExpEl s e i f s = l i s t<ExpElse i f >;63 type EnumDef = Absyn . EnumDef ;

type EnumLiteral = Absyn . EnumLiteral ;65 type EnumLiterals = l i s t<EnumLiteral >;

type Mod i f i ca t i on = Absyn . Mod i f i ca t i on ;67 type Boolean3 = tuple<Boolean ,Boolean ,Boolean>;

type Boolean2 = tuple<Boolean ,Boolean>;69 type ElementArg = Absyn . ElementArg ;

type ElementArgs = l i s t<ElementArg>;71 type Each = Absyn . Each ;

type EqMod=Absyn .EqMod ;73 type ComponentCondition = Absyn . ComponentCondition ;

type ExternalDec l = Absyn . ExternalDec l ;75 type Annotation = Absyn . Annotation ;

77 constant l i s t<String> lstSemValue3 = {} ;

79 constant l i s t<String> lstSemValue = {” e r r o r ” , ” $undef ined ” , ”ALGORITHM” , ”AND” , ”ANNOTATION” ,

81 ”BLOCK” , ”CLASS” , ”CONNECT” , ”CONNECTOR” , ”CONSTANT” , ”DISCRETE” , ”DER” ,

”DEFINEUNIT” , ”EACH” , ”ELSE” , ”ELSEIF” , ”ELSEWHEN” , ”END” ,83 ”ENUMERATION” , ”EQUATION” , ”ENCAPSULATED” , ”EXPANDABLE” , ”

EXTENDS” ,”CONSTRAINEDBY” , ”EXTERNAL” , ”FALSE” , ”FINAL” , ”FLOW” , ”FOR” ,

85 ”FUNCTION” , ”IF” , ”IMPORT” , ”IN” , ”INITIAL” , ”INNER” , ”INPUT” ,”LOOP” , ”MODEL” , ”NOT” , ”OUTER” , ”OPERATOR” , ”OVERLOAD” , ”OR” ,

87 ”OUTPUT” , ”PACKAGE” , ”PARAMETER” , ”PARTIAL” , ”PROTECTED” , ”PUBLIC” ,

”RECORD” , ”REDECLARE” , ”REPLACEABLE” , ”RESULTS” , ”THEN” , ”TRUE” ,

89 ”TYPE” , ”REAL” , ”WHEN” , ”WHILE” , ”WITHIN” , ”RETURN” , ”BREAK” ,” . ” , ” ( ” , ” ) ” , ” [ ” , ” ] ” , ”{” , ”}” , ”=” ,

91 ”ASSIGN” , ”COMMA” , ”COLON” , ”SEMICOLON” , ”CODE” , ”CODE NAME” ,”CODE EXP” ,

”CODE VAR” , ”PURE” , ”IMPURE” , ” I d e n t i t y ” , ”DIGIT” , ”INTEGER” ,93 ”∗” , ”−” , ”+” , ”<=” , ”<>” , ”<” , ”>” ,

”>=” , ”==” , ”ˆ” , ”SLASH” , ”STRING” , ”.+” , ”.−” ,95 ” .∗ ” , ” . / ” , ” .∗ ” , ”STREAM” , ”AS” , ”CASE” , ”EQUALITY” ,

Page 202: OMCCp: A MetaModelica Based Parser Generator Applied to ...

182 APPENDIX F. MODELICA GRAMMAR

”FAILURE” , ”GUARD” , ”LOCAL” , ”MATCH” , ”MATCHCONTINUE” , ”UNIONTYPE” ,

97 ”ALLWILD” , ”WILD” , ”SUBTYPEOF” , ”COLONCOLON” , ”MOD” , ”ENDIF” ,”ENDFOR” ,

”ENDWHILE” , ”ENDWHEN” , ”ENDCLASS” , ”ENDMATCHCONTINUE” , ”ENDMATCH” ,

99 ” $accept ” ,”program” , ” with in ” , ” c l a s s e s l i s t ” , ” c l a s s ” , ” c l a s s p r e f i x ” ,

101 ” encapsu lated ” , ” p a r t i a l ” , ” r e s t r i c t i o n ” , ” c l a s s d e f ” ,” c l a s sde f enumera t i on ” , ” c l a s s d e f d e r i v e d ” , ” enumeration ” , ”

enuml i s t ” ,103 ” enuml i t e r a l ” , ” c l a s s p a r t s ” , ” c l a s s p a r t ” , ” r e s t C l a s s ” ,

” a l g o r i t h m s e c t i o n ” , ” a lgor i thmitem ” , ” a lgor i thm ” , ”i f a l g o r i t h m ” ,

105 ” a l g e l s e i f s ” , ” a l g e l s e i f ” , ” when algorithm ” , ” a lge l s ewhens ” ,” a lge l s ewhen ” , ” e q u a t i o n s e c t i o n ” , ” equat ion item ” , ” equat ion ” ,

107 ” when equation ” , ” e l sewhens ” , ” elsewhen ” , ” f o r i t e r a t o r s ” , ”f o r i t e r a t o r ” ,

” i f e q u a t i o n ” , ” e l s e i f s ” , ” e l s e i f ” , ” e lementItems ” , ”elementItem ” ,

109 ” element ” , ” componentclause ” , ” componentitems” , ”componentitem” ,

”component” , ” mod i f i c a t i on ” , ” redec la rekeywords ” , ” inne rou t e r ”,

111 ” importe lementspec ” , ” c l a s s e l e me nt s pe c ” , ” import ” , ”e lementspec ” ,

” elementAttr ” , ” v a r i a b i l i t y ” , ” d i r e c t i o n ” , ” typespec ” , ”arrayComplex” ,

113 ” typespecs ” , ” a r r aySubsc r i p t s ” , ”arrayDim” , ” f u n c t i o n c a l l ” ,” f u n c t i o n a r g s ” , ”namedargs” , ”namedarg” , ”exp” , ”matchcont” , ”

i f e x p ” ,115 ” e x p e l s e i f s ” , ” e x p e l s e i f ” , ” matchloca l ” , ” ca s e s ” , ” case ” , ”

casearg ” ,” simpleExp” , ” h e a d t a i l ” , ”rangeExp” , ” l o g i c e x p ” , ” l og i c t e rm ” ,

117 ” l o g f a c t o r ” , ” r e l t e rm ” , ”addterm” , ”term” , ” f a c t o r ” , ”expElement” ,

” tup l e ” , ” e x p l i s t ” , ” e x p l i s t 2 ” , ” c r e f ” , ” woperator ” , ”sope ra to r ” ,

119 ”power” , ” r e lOperato r ” , ”path” , ” ident ” , ” s t r i n g ” , ”comment” } ;

121 %}

123 %token T ALGORITHM%token T AND

125 %token T ANNOTATION%token BLOCK

127 %token CLASS%token CONNECT

129 %token CONNECTOR%token CONSTANT

131 %token DISCRETE%token DER

133 %token DEFINEUNIT%token EACH

135 %token ELSE%token ELSEIF

137 %token ELSEWHEN

Page 203: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.2. PARSERMODELICA.Y 183

%token T END139 %token ENUMERATION

%token EQUATION141 %token ENCAPSULATED

%token EXPANDABLE143 %token EXTENDS

%token CONSTRAINEDBY145 %token EXTERNAL

%token T FALSE147 %token FINAL

%token FLOW149 %token FOR

%token FUNCTION151 %token IF

%token IMPORT153 %token T IN

%token INITIAL155 %token INNER

%token T INPUT157 %token LOOP

%token MODEL159 %token T NOT

%token T OUTER161 %token OPERATOR

%token OVERLOAD163 %token T OR

%token T OUTPUT165 %token T PACKAGE

%token PARAMETER167 %token PARTIAL

%token PROTECTED169 %token PUBLIC

%token RECORD171 %token REDECLARE

%token REPLACEABLE173 %token RESULTS

%token THEN175 %token T TRUE

%token TYPE177 %token UNSIGNED REAL

%token WHEN179 %token WHILE

%token WITHIN181 %token RETURN

%token BREAK183 %token DOT

%token LPAR185 %token RPAR

%token LBRACK187 %token RBRACK

%token LBRACE189 %token RBRACE

%token EQUALS191 %token ASSIGN

%token COMMA193 %token COLON

%token SEMICOLON

Page 204: OMCCp: A MetaModelica Based Parser Generator Applied to ...

184 APPENDIX F. MODELICA GRAMMAR

195 %token CODE%token CODE NAME

197 %token CODE EXP%token CODE VAR

199 %token PURE%token IMPURE

201 %token IDENT%token DIGIT

203 %token UNSIGNED INTEGER

205 %token STAR%token MINUS

207 %token PLUS%token LESSEQ

209 %token LESSGT%token LESS

211 %token GREATER%token GREATEREQ

213 %token EQEQ%token POWER

215 %token SLASH

217 %token STRING

219 %token PLUS EW%token MINUS EW

221 %token STAR EW%token SLASH EW

223 %token POWEREW

225 %token STREAM

227 %token AS%token CASE

229 %token EQUALITY%token FAILURE

231 %token GUARD%token LOCAL

233 %token MATCH%token MATCHCONTINUE

235 %token UNIONTYPE%token ALLWILD

237 %token WILD%token SUBTYPEOF

239 %token COLONCOLON%token MOD

241 %token ENDIF%token ENDFOR

243 %token ENDWHILE%token ENDWHEN

245 %token ENDCLASS%token ENDMATCHCONTINUE

247 %token ENDMATCH//%expect 42

249

251

Page 205: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.2. PARSERMODELICA.Y 185

%%253

/∗ Yacc BNF grammar o f the Modelica+MetaModelica language ∗/255

program : c l a s s e s l i s t257 { ( absyntree ) [ Program ] = Absyn .

PROGRAM( $1 [ l s t C l a s s ] , Absyn .TOP( ) , Absyn .TIMESTAMP(System. getCurrentTime ( ) ,System .getCurrentTime ( ) ) ) ; }

| with in c l a s s e s l i s t259 { ( absyntree ) [ Program ] = Absyn .

PROGRAM( $2 [ l s t C l a s s ] , $1 [Within ] , Absyn .TIMESTAMP(System . getCurrentTime ( ) ,System . getCurrentTime ( ) ) ) ; }

261with in : WITHIN path SEMICOLON { $$ [ Within ] =

Absyn .WITHIN( $2 [ Path ] ) ; }263

c l a s s e s l i s t : class SEMICOLON { $$ [ l s t C l a s s ] = $1 [Class ] : : { } ; }

265 | class SEMICOLON c l a s s e s l i s t { $$ [l s t C l a s s ] = $1 [ Class ] : : $2 [ l s t C l a s s ] ;}

/∗ r e s t r i c t i o n IDENT c l a s s d e f T ENDIDENT SEMICOLON

267 { i f ( not s t r ingEqua l ( $2 , $5 ) )then p r i n t ( Types .p r i n t I n f o E r r o r ( i n f o ) + ”Error : The i d e n t i f i e r ats t a r t and end are d i f f e r e n t’” + $2 + ” ’”) ;

t rue = ( $2 == $5 ) ;269 end i f ; $$ [ Class ] = Absyn .

CLASS( $2 , f a l s e , f a l s e , f a l s e, $1 [ R e s t r i c t i o n ] , $3 [ClassDef ] , i n f o ) ; }

∗/271

class : r e s t r i c t i o n IDENT c l a s s d e f273 { $$ [ Class ] = Absyn .CLASS( $2 ,

false , false , false , $1 [R e s t r i c t i o n ] , $3 [ ClassDef ] ,i n f o ) ; }

| c l a s s p r e f i x r e s t r i c t i o n IDENT c l a s s d e f275 { ( v1Boolean , v2Boolean , v3Boolean

) = $1 [ Boolean3 ] ;$$ [ Class ] = Absyn .CLASS( $3 ,

v3Boolean , v1Boolean ,v2Boolean , $2 [ R e s t r i c t i o n ] ,$4 [ ClassDef ] , i n f o ) ; }

277c l a s s d e f : s t r i n g ENDCLASS

279 { $$ [ ClassDef ] = Absyn .PARTS({} ,{} ,SOME( $1 ) ) ; }

Page 206: OMCCp: A MetaModelica Based Parser Generator Applied to ...

186 APPENDIX F. MODELICA GRAMMAR

|ENDCLASS281 { $$ [ ClassDef ] = Absyn .PARTS({} ,{} ,

NONE( ) ) ; }| c l a s s p a r t s ENDCLASS

283 { $$ [ ClassDef ] = Absyn .PARTS({} , $1 [C las sPart s ] ,NONE( ) ) ; }

| s t r i n g c l a s s p a r t s ENDCLASS285 { $$ [ ClassDef ] = Absyn .PARTS({} , $2 [

C las sPart s ] ,SOME( $1 ) ) ; }| c l a s sde f enumera t i on

287 { $$ [ ClassDef ] = $1 [ ClassDef ] ; } ;| c l a s s d e f d e r i v e d

289 { $$ [ ClassDef ] = $1 [ ClassDef ] ; } ;

291c l a s s p r e f i x : FINAL encapsu lated p a r t i a l

293 { $$ [ Boolean3 ] = ( true , $2 [Boolean ] , $3 [Boolean ] ) ; }

| ENCAPSULATED p a r t i a l295 { $$ [ Boolean3 ] = ( false , true , $2 [Boolean

] ) ; }| PARTIAL

297 { $$ [ Boolean3 ] = ( false , false , true ) ; }

299 encapsu lated : ENCAPSULATED { $$ [Boolean ] = true ; }| /∗ empty ∗/ { $$ [Boolean ] = fa l se ; }

301p a r t i a l : PARTIAL { $$ [Boolean ] = true ; }

303 | /∗ empty ∗/ { $$ [Boolean ] = fa l se ; }

305 f ina l : FINAL { $$ [Boolean ] = true ; }| /∗ empty ∗/ { $$ [Boolean ] = fa l se ; }

307r e s t r i c t i o n : CLASS { $$ [ R e s t r i c t i o n ] = Absyn .

R CLASS( ) ; }309 | MODEL { $$ [

R e s t r i c t i o n ]= Absyn .

R MODEL( ) ; }| RECORD { $$ [

R e s t r i c t i o n ]= Absyn .

R RECORD( ) ;}

311 | T PACKAGE { $$[ R e s t r i c t i o n] = Absyn .R PACKAGE( ) ;}

| TYPE { $$ [R e s t r i c t i o n ]= Absyn .

R TYPE( ) ; }313 | FUNCTION { $$ [

R e s t r i c t i o n ]= Absyn .

R FUNCTION( )

Page 207: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.2. PARSERMODELICA.Y 187

; }| UNIONTYPE { $$

[ R e s t r i c t i o n] = Absyn .R UNIONTYPE( ) ; }

315 | BLOCK { $$ [R e s t r i c t i o n ]= Absyn .

R BLOCK( ) ; }| CONNECTOR { $$

[ R e s t r i c t i o n] = Absyn .R CONNECTOR( ) ; }

317 | EXPANDABLECONNECTOR {$$ [R e s t r i c t i o n ]= Absyn .

R EXP CONNECTOR( ) ; }

| ENUMERATION {$$ [R e s t r i c t i o n ]= Absyn .

R ENUMERATION( ) ; }

319 | OPERATORFUNCTION {$$ [R e s t r i c t i o n ]= Absyn .

R OPERATOR FUNCTION( ) ; }

| OPERATORRECORD { $$ [R e s t r i c t i o n ]= Absyn .

R OPERATOR RECORD( ) ; }

321 | OPERATOR { $$ [ R e s t r i c t i o n ] = Absyn.R OPERATOR( ) ; }

323

325 c l a s sde f enumera t i on : EQUALS ENUMERATION LPAR enumeration RPARcomment

{ $$ [ ClassDef ] = Absyn .ENUMERATION( $4 [EnumDef ] ,SOME( $6 [ Comment ] ) ) ; }

327c l a s s d e f d e r i v e d : EQUALS typespec e lementargs2 comment

329 { $$ [ ClassDef ] = Absyn .DERIVED( $2 [TypeSpec ] , Absyn .ATTR( false , false ,Absyn .VAR( ) , Absyn . BIDIR ( ) ,{} ) , $3 [ElementArgs ] ,SOME( $4 [ Comment ] ) ) ; }

Page 208: OMCCp: A MetaModelica Based Parser Generator Applied to ...

188 APPENDIX F. MODELICA GRAMMAR

| EQUALS elementAttr typespec e lementargs2comment

331 { $$ [ ClassDef ] = Absyn .DERIVED( $3 [TypeSpec ] , $2 [ ElementAttr ibutes ] , $4 [ElementArgs ] ,SOME( $5 [ Comment ] ) ) ; }

333 enumeration : enuml i s t { $$ [ EnumDef ] = Absyn .ENUMLITERALS( $1 [ EnumLiterals ] ) ; }

| COLON { $$ [ EnumDef ] = Absyn .ENUM COLON( ) ;}

335enuml i s t : enuml i t e r a l { $$ [ EnumLiterals ] = $1 [

EnumLiteral ] : : { } ; }337 | enuml i t e r a l COMMA enuml i s t { $$ [

EnumLiterals ] = $1 [ EnumLiteral ] : : $3 [EnumLiterals ] ; }

339 enuml i t e r a l : i dent comment { $$ [ EnumLiteral ] = Absyn .ENUMLITERAL( $1 [ Ident ] ,SOME( $2 [ Comment ] ) ) ; }

341 c l a s s p a r t s : c l a s s p a r t { $$ [ Clas sPart s ] = $1 [ ClassPart] : : { } ; }

| c l a s s p a r t c l a s s p a r t s { $$ [ Clas sPart s ] =$1 [ ClassPart ] : : $2 [ C las sPart s ] ; }

343c l a s s p a r t : e lementItems { $$ [ ClassPart ] = Absyn .

PUBLIC( $1 [ ElementItems ] ) ; }345 | r e s t C l a s s { $$ [ ClassPart ] = $1 [ ClassPart

] ; }

347

349 r e s t C l a s s : PUBLIC elementItems { $$ [ ClassPart ] =Absyn .PUBLIC( $1 [ ElementItems ] ) ; }

| PUBLIC { $$ [ ClassPart ] = Absyn .PUBLIC({} ) ; } // adds s h i f t / reducec o n f l i c t s

351 | PROTECTED elementItems { $$ [ ClassPart ]= Absyn .PROTECTED( $1 [ ElementItems ] )

; }| PROTECTED { $$ [ ClassPart ] = Absyn .

PROTECTED({} ) ; } // adds s h i f t /reduce c o n f l i c t s

353 | EQUATION { $$ [ ClassPart ] = Absyn .EQUATIONS({} ) ; }

| EQUATION e q u a t i o n s e c t i o n { $$ [ClassPart ] = Absyn .EQUATIONS( $1 [EquationItems ] ) ; }

355 | INITIAL EQUATION e q u a t i o n s e c t i o n { $$ [ClassPart ] = Absyn . INITIALEQUATIONS($1 [ EquationItems ] ) ; }

| T ALGORITHM { $$ [ ClassPart ] = Absyn .ALGORITHMS({} ) ; }

357 | T ALGORITHM a l g o r i t h m s e c t i o n { $$ [ClassPart ] = Absyn .ALGORITHMS( $1 [AlgorithmItems ] ) ; }

Page 209: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.2. PARSERMODELICA.Y 189

| INITIAL T ALGORITHM a l g o r i t h m s e c t i o n {$$ [ ClassPart ] = Absyn .

INITIALALGORITHMS( $1 [ AlgorithmItems] ) ; }

359 | e x t e r n a l { $$ [ ClassPart ] = $1 [ClassPart ] ; }

361 e x t e r n a l : EXTERNAL exte rna lDec l SEMICOLON { $$ [ClassPart ] = Absyn .EXTERNAL( $2 [ ExternalDec l ] ,NONE( ) ) ; }

| EXTERNAL exte rna lDec l SEMICOLONannotat ion SEMICOLON { $$ [ ClassPart ]= Absyn .EXTERNAL( $2 [ ExternalDec l ] ,SOME( $3 [ Annotation ] ) ) ; }

363ex t e rna lDec l : s t r i n g { $$ [ ExternalDec l ] = Absyn .

EXTERNALDECL(NONE( ) ,SOME( $1 ) ,NONE( ) ,{} ,NONE( ) ) ; }365 | s t r i n g c r e f EQUALS ident LPAR e x p l i s t 2

RPAR { $$ [ ExternalDec l ] = Absyn .EXTERNALDECL(SOME( $4 [ Ident ] ) ,SOME( $1 ),SOME( $2 [ ComponentRef ] ) , $6 [ Exps ] ,NONE( ) ) ; }

| s t r i n g c r e f EQUALS ident LPAR e x p l i s t 2RPAR annotat ion { $$ [ ExternalDec l ] =Absyn .EXTERNALDECL(SOME( $4 [ Ident ] ) ,SOME( $1 ) ,SOME( $2 [ ComponentRef ] ) , $6 [Exps ] ,SOME( $8 [ Annotation ] ) ) ; }

367 | s t r i n g ident LPAR e x p l i s t 2 RPARannotat ion { $$ [ ExternalDec l ] = Absyn.EXTERNALDECL(SOME( $2 [ Ident ] ) ,SOME( $1) ,NONE( ) , $4 [ Exps ] ,SOME( $6 [ Annotation] ) ) ; }

| s t r i n g ident LPAR e x p l i s t 2 RPAR { $$ [ExternalDec l ] = Absyn .EXTERNALDECL(SOME( $2 [ Ident ] ) ,SOME( $1 ) ,NONE( ) , $4 [Exps ] ,NONE( ) ) ; }

369/∗ ALGORITHMS ∗/

371a l g o r i t h m s e c t i o n : a lgor i thmitem SEMICOLON { $$ [

AlgorithmItems ] = $1 [ AlgorithmItem ] : : { } ; }373 | a lgor i thmitem SEMICOLON

a l g o r i t h m s e c t i o n { $$ [ AlgorithmItems] = $1 [ AlgorithmItem ] : : $2 [AlgorithmItems ] ; }

375 a lgor i thmitem : algorithm comment{ $$ [ AlgorithmItem ] = Absyn .

ALGORITHMITEM( $1 [ Algorithm ] ,SOME($2 [ Comment ] ) , i n f o ) ; }

377algorithm : simpleExp ASSIGN exp // TOREV: c r e f

or any exp? { $$ [ Algorithm ] = Absyn .ALG ASSIGN( Absyn .CREF($1 [ ComponentRef ] ) , $2 [ Exp ] ) ; }

379 { $$ [ Algorithm ] = Absyn .ALG ASSIGN($1 [ Exp ] , $2 [ Exp ] ) ; }

| c r e f f u n c t i o n c a l l

Page 210: OMCCp: A MetaModelica Based Parser Generator Applied to ...

190 APPENDIX F. MODELICA GRAMMAR

381 { $$ [ Algorithm ] = Absyn .ALG NORETCALL( $1 [ ComponentRef ] ,$2 [ FunctionArgs ] ) ; }

| tup l e ASSIGN exp383 { $$ [ Algorithm ] = Absyn .ALG ASSIGN(

$1 [ Exp ] , $3 [ Exp ] ) ; }| RETURN

385 { $$ [ Algorithm ] = Absyn .ALG RETURN( ); }

| BREAK387 { $$ [ Algorithm ] = Absyn .ALG BREAK( )

; }| i f a l g o r i t h m

389 { $$ [ Algorithm ] = $1 [ Algorithm ] ; }| when algorithm

391 { $$ [ Algorithm ] = $1 [ Algorithm ] ; }| FOR f o r i t e r a t o r s LOOP a l g o r i t h m s e c t i o n

ENDFOR393 { $$ [ Algorithm ] = Absyn .ALG FOR( $3 [

F o r I t e r a t o r s ] , $5 [ AlgorithmItems] ) ; }

| WHILE exp LOOP a l g o r i t h m s e c t i o nENDWHILE

395 { $$ [ Algorithm ] = Absyn .ALG WHILE( $3[ Exp ] , $5 [ AlgorithmItems ] ) ; }

397 i f a l g o r i t h m : IF exp THEN ENDIF { $$ [ Algorithm ] =Absyn . ALG IF( $2 [ Exp ] ,{} ,{} ,{} ) ; } // warning empty i f

| IF exp THEN a l g o r i t h m s e c t i o n ENDIF { $$ [Algorithm ] = Absyn . ALG IF( $2 [ Exp ] , $4 [AlgorithmItems ] ,{} ,{} ) ; }

399 | IF exp THEN a l g o r i t h m s e c t i o n ELSEa l g o r i t h m s e c t i o n ENDIF { $$ [ Algorithm] = Absyn . ALG IF( $2 [ Exp ] , $4 [AlgorithmItems ] ,{} , $6 [ AlgorithmItems] ) ; }

| IF exp THEN a l g o r i t h m s e c t i o n a l g e l s e i f sENDIF { $$ [ Algorithm ] = Absyn . ALG IF

( $2 [ Exp ] , $4 [ AlgorithmItems ] , $5 [A l g E l s e i f s ] , { } ) ; }

401 | IF exp THEN a l g o r i t h m s e c t i o n a l g e l s e i f sELSE a l g o r i t h m s e c t i o n ENDIF { $$ [

Algorithm ] = Absyn . ALG IF( $2 [ Exp ] , $4 [AlgorithmItems ] , $5 [ A l g E l s e i f s ] , $7 [AlgorithmItems ] ) ; }

403 a l g e l s e i f s : a l g e l s e i f { $$ [ A l g E l s e i f s ] = $1 [A l g E l s e i f ] : : { } ; }

| a l g e l s e i f a l g e l s e i f s { $$ [ A l g E l s e i f s ]= $1 [ A l g E l s e i f ] : : $2 [ A l g E l s e i f s ] ; }

405a l g e l s e i f : ELSEIF exp THEN a l g o r i t h m s e c t i o n { $$

[ A l g E l s e i f ] = ( $2 [ Exp ] , $4 [ AlgorithmItems ] ) ; }407

when algorithm : WHEN exp THEN a l g o r i t h m s e c t i o n ENDWHEN409 { $$ [ Algorithm ] = Absyn .ALG WHEN A( $2

[ Exp ] , $4 [ AlgorithmItems ] , { } ) ; }

Page 211: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.2. PARSERMODELICA.Y 191

| WHEN exp THEN a l g o r i t h m s e c t i o na lge l s ewhens ENDWHEN

411 { $$ [ Algorithm ] = Absyn .ALG WHEN A( $2[ Exp ] , $4 [ AlgorithmItems ] , $5 [AlgElsewhens ] ) ; }

413 a lge l s ewhens : a lge l s ewhen { $$ [ AlgElsewhens ] =$1 [ AlgElsewhen ] : : { } ; }

| a lge l sewhen a lge l s ewhens { $$ [AlgElsewhens ] = $1 [ AlgElsewhen ] : : $2 [AlgElsewhens ] ; }

415a lge l sewhen : ELSEWHEN exp THEN a l g o r i t h m s e c t i o n

{ $$ [ AlgElsewhen ] = ( $2 [ Exp ] , $4 [ AlgorithmItems ] ) ; }417

419 /∗ EQUATIONS ∗/e q u a t i o n s e c t i o n : equat ion item SEMICOLON { $$ [

EquationItems ] = $1 [ EquationItem ] : : { } ; }421 | equat ion item SEMICOLON e q u a t i o n s e c t i o n

{ $$ [ EquationItems ] = $1 [EquationItem ] : : $2 [ EquationItems ] ; }

423 equat ion item : equation comment{ $$ [ EquationItem ] = Absyn .

EQUATIONITEM( $1 [ Equation ] ,SOME( $2 [Comment ] ) , i n f o ) ; }

425equation : exp EQUALS exp

427 { $$ [ Equation ] = Absyn .EQ EQUALS( $1[ Exp ] , $3 [ Exp ] ) ; }

| i f e q u a t i o n429 { $$ [ Equation ] = $1 [ Equation ] ; }

| when equation431 { $$ [ Equation ] = $1 [ Equation ] ; }

| CONNECT LPAR c r e f COMMA c r e f RPAR433 { $$ [ Equation ] = Absyn .EQ CONNECT(

$3 [ ComponentRef ] , $5 [ComponentRef ] ) ; }

| FOR f o r i t e r a t o r s LOOP e q u a t i o n s e c t i o nENDFOR

435 { $$ [ Equation ] = Absyn .EQ FOR( $3 [F o r I t e r a t o r s ] , $5 [ EquationItems] ) ; }

| c r e f f u n c t i o n c a l l { $$ [ Equation ] =Absyn .EQ NORETCALL( $1 [ ComponentRef ] ,$2 [ FunctionArgs ] ) ; }

437when equation : WHEN exp THEN e q u a t i o n s e c t i o n ENDWHEN

439 { $$ [ Equation ] = Absyn .EQ WHEN E( $2 [Exp ] , $4 [ EquationItems ] , { } ) ; }

| WHEN exp THEN e q u a t i o n s e c t i o n e l sewhensENDWHEN

441 { $$ [ Equation ] = Absyn .EQ WHEN E( $2 [Exp ] , $4 [ EquationItems ] , $5 [Elsewhens ] ) ; }

Page 212: OMCCp: A MetaModelica Based Parser Generator Applied to ...

192 APPENDIX F. MODELICA GRAMMAR

443 e l sewhens : e lsewhen { $$ [ Elsewhens ] = $1 [Elsewhen ] : : { } ; }

| elsewhen e l sewhens { $$ [ Elsewhens ] =$1 [ Elsewhen ] : : $2 [ Elsewhens ] ; }

445elsewhen : ELSEWHEN exp THEN e q u a t i o n s e c t i o n { $$

[ Elsewhen ] = ( $2 [ Exp ] , $4 [ EquationItems ] ) ; }447

f o r i t e r a t o r s : f o r i t e r a t o r { $$ [ F o r I t e r a t o r s ] = $1 [F o r I t e r a t o r ] : : { } ; }

449 | f o r i t e r a t o r COMMA f o r i t e r a t o r s { $$ [F o r I t e r a t o r s ] = $1 [ F o r I t e r a t o r ] : : $2 [F o r I t e r a t o r s ] ; }

451 f o r i t e r a t o r : IDENT { $$ [ F o r I t e r a t o r ] = Absyn .ITERATOR( $1 ,NONE( ) ,NONE( ) ) ; }

| IDENT T IN exp { $$ [ F o r I t e r a t o r ] = Absyn.ITERATOR( $1 ,NONE( ) ,SOME( $3 [ Exp ] ) ) ; }

453i f e q u a t i o n : IF exp THEN e q u a t i o n s e c t i o n ENDIF { $$ [

Equation ] = Absyn . EQ IF( $2 [ Exp ] , $4 [ EquationItems ] ,{} ,{} ) ; }455 | IF exp THEN e q u a t i o n s e c t i o n ELSE

e q u a t i o n s e c t i o n ENDIF { $$ [ Equation ] =Absyn . EQ IF( $2 [ Exp ] , $4 [ EquationItems

] ,{} , $6 [ EquationItems ] ) ; }| IF exp THEN e q u a t i o n s e c t i o n e l s e i f s

ENDIF { $$ [ Equation ] = Absyn . EQ IF( $2 [Exp ] , $4 [ EquationItems ] , $5 [ E l s e i f s ] , { } ); }

457 | IF exp THEN e q u a t i o n s e c t i o n e l s e i f s ELSEe q u a t i o n s e c t i o n ENDIF { $$ [ Equation ]

= Absyn . EQ IF( $2 [ Exp ] , $4 [ EquationItems] , $5 [ E l s e i f s ] , $7 [ EquationItems ] ) ; }

459 e l s e i f s : e l s e i f { $$ [ E l s e i f s ] = $1 [ E l s e i f ] : : { } ;}

| e l s e i f e l s e i f s { $$ [ E l s e i f s ] = $1 [E l s e i f ] : : $2 [ E l s e i f s ] ; }

461e l s e i f : ELSEIF exp THEN e q u a t i o n s e c t i o n { $$ [

E l s e i f ] = ( $2 [ Exp ] , $4 [ EquationItems ] ) ; }463

/∗ Express ions and Elements ∗/465

elementItems : elementItem { $$ [ ElementItems ] = $1 [ElementItem ] : : { } ; }

467 | elementItem elementItems { $$ [ElementItems ] = $1 [ ElementItem ] : : $2 [ElementItems ] ; }

469elementItem : element SEMICOLON { $$ [ ElementItem ] =

Absyn .ELEMENTITEM( $1 [ Element ] ) ; }471 | annotat ion SEMICOLON { $$ [ ElementItem ] =

Absyn .ANNOTATIONITEM( $1 [ Annotation ] ) ; }

473 element : componentclause

Page 213: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.2. PARSERMODELICA.Y 193

{ $$ [ Element ] = $1 [ Element ] ; }475 | c lassElement2

{ $$ [ Element ] = $1 [ Element ] ; }477 | importe lementspec

{ $$ [ Element ] = Absyn .ELEMENT( false ,NONE( ) , Absyn .NOT INNER OUTER( ) , ”IMPORT” ,$1 [ ElementSpec ] , in fo ,NONE( ) ) ; }

479 | extends{ $$ [ Element ] = Absyn .ELEMENT( false ,NONE

( ) , Absyn .NOT INNER OUTER( ) , ”EXTENDS” ,$1 [ ElementSpec ] , in fo ,NONE( ) ) ; }

481 | FINAL f ina lE l ement{ $$ [ Element ] = $2 [ Element ] ; }

483

485 c lassElement2 : c l a s s e l e me n t s pe c{ $$ [ Element ] = Absyn .ELEMENT( false ,NONE

( ) , Absyn .NOT INNER OUTER( ) , ”CLASS” ,$1 [ ElementSpec ] , in fo ,NONE( ) ) ; }

487 | REDECLARE c la s s e l e me nt s pe c{ $$ [ Element ] = Absyn .ELEMENT( false ,SOME

( Absyn .REDECLARE( ) ) , Absyn .NOT INNER OUTER( ) , ”CLASS” , $1 [ElementSpec ] , in fo ,NONE( ) ) ; }

489f ina lE l ement : i nne rou t e r ident e lementspec

491 { $$ [ Element ] = Absyn .ELEMENT(true ,NONE( ) , $1 [ InnerOuter ] ,$2 [ Ident ] , $3 [ ElementSpec ] ,in fo ,NONE( ) ) ; }

| i dent e lementspec493 { $$ [ Element ] = Absyn .ELEMENT(

true ,NONE( ) , Absyn .NOT INNER OUTER( ) , $1 [ Ident ] ,$2 [ ElementSpec ] , in fo ,NONE( ) ); }

// | e lementspec // casues reduce / reducec o n f l i c t s

495 // { $$ [ Element ] = Absyn .ELEMENT( true ,NONE( ) , Absyn .NOT INNER OUTER( ) ,”ELEMENTSPEC” , $1 [ ElementSpec ] , in fo ,NONE( ) ) ;}

497

499 componentclause : e lementspec{ $$ [ Element ] = Absyn .ELEMENT( false ,NONE

( ) , Absyn .NOT INNER OUTER( ) , ”ELEMENTSPEC” , $1 [ ElementSpec ] , in fo ,NONE( ) ) ; }

501 | i nne rou t e r e lementspec{ $$ [ Element ] = Absyn .ELEMENT(

false ,NONE( ) , $1 [ InnerOuter ] ,”ELEMENTSPEC” , $2 [ ElementSpec] , in fo ,NONE( ) ) ; }

503 | r edec la rekeywords f ina l i nne rou t e rident e lementspec

Page 214: OMCCp: A MetaModelica Based Parser Generator Applied to ...

194 APPENDIX F. MODELICA GRAMMAR

{ $$ [ Element ] = Absyn .ELEMENT( $2[Boolean ] ,SOME( $1 [RedeclareKeywords ] ) , $3 [InnerOuter ] , $4 [ Ident ] , $5 [ElementSpec ] , in fo ,NONE( ) ) ; }

505 | r edec la rekeywords f ina l i dente lementspec{ $$ [ Element ] = Absyn .ELEMENT( $2

[Boolean ] ,SOME( $1 [RedeclareKeywords ] ) , Absyn .NOT INNER OUTER( ) , $3 [ Ident ] ,$4 [ ElementSpec ] , in fo ,NONE( ) ); }

507

509 componentitems : componentitem { $$ [ ComponentItems ] = $1 [ComponentItem ] : : { } ; }

| componentitem COMMA componentitems { $$ [ComponentItems ] = $1 [ ComponentItem ] : : $2 [ComponentItems ] ; }

511componentitem : component comment { $$ [ ComponentItem ] =

Absyn .COMPONENTITEM( $1 [ Component ] ,NONE( ) ,SOME( $2 [ Comment ] ) ) ;}

513 | component componentcondit ion comment { $$ [ComponentItem ] = Absyn .COMPONENTITEM( $1 [Component ] ,SOME( $2 [ ComponentCondition ] ) ,SOME( $3 [ Comment ] ) ) ; }

515 componentcondit ion : IF exp { $$ [ ComponentCondition ] = $1 [ Exp ] ;}

517 component : ident a r raySubsc r i p t s mod i f i c a t i on { $$ [Component ] = Absyn .COMPONENT( $1 [ Ident ] , $2 [ ArrayDim ] ,SOME( $3 [Mod i f i ca t i on ] ) ) ; }

| i dent a r raySubsc r i p t s { $$ [ Component ] =Absyn .COMPONENT( $1 [ Ident ] , $2 [ ArrayDim ] ,NONE( ) ) ; }

519mod i f i c a t i on : EQUALS exp { $$ [ Mod i f i ca t i on ] = Absyn .

CLASSMOD({} , Absyn .EQMOD( $2 [ Exp ] , i n f o ) ) ; }521 | ASSIGN exp { $$ [ Mod i f i ca t i on ] = Absyn .

CLASSMOD({} , Absyn .EQMOD( $2 [ Exp ] , i n f o ) ) ;}

| c l a s s m o d i f i c a t i o n { $$ [ Mod i f i ca t i on ] = $1[ Mod i f i ca t i on ] ; }

523c l a s s m o d i f i c a t i o n : e l ementargs

525 { $$ [ Mod i f i ca t i on ] = Absyn .CLASSMOD( $1 [ElementArgs ] , Absyn .NOMOD( ) ) ; }

| e lementargs EQUALS exp527 { $$ [ Mod i f i ca t i on ] = Absyn .CLASSMOD( $1 [

ElementArgs ] , Absyn .EQMOD( $3 [ Exp ] , i n f o )) ; }

529 annotat ion : T ANNOTATION elementargs { $$ [ Annotation ]=Absyn .ANNOTATION( $1 [ ElementArgs ] ) ; }

Page 215: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.2. PARSERMODELICA.Y 195

531 e lementargs : LPAR argument l i s t RPAR { $$ [ ElementArgs ] =$1 [ ElementArgs ] ; }

533 e lementargs2 : LPAR argument l i s t RPAR { $$ [ ElementArgs ]= $1 [ ElementArgs ] ; }

| /∗ empty ∗/ { $$ [ ElementArgs ] = {} ; }535

argument l i s t : e lementarg { $$ [ ElementArgs ] = {$1 [ElementArg ] } ; }

537 | e lementarg COMMA argument l i s t { $$ [ElementArgs ] = $1 [ ElementArg ] : : $2 [ElementArgs ] ; }

539 elementarg : e a c h p r e f i x f ina l c r e f{ $$ [ ElementArg ] = Absyn .MODIFICATION( $2 [

Boolean ] , $1 [ Each ] , $3 [ ComponentRef ] ,NONE( ) ,NONE( ) ) ; }

541 | e a c h p r e f i x f ina l c r e f mod i f i c a t i on{ $$ [ ElementArg ] = Absyn .MODIFICATION( $2 [

Boolean ] , $1 [ Each ] , $3 [ ComponentRef ] ,SOME( $4 [ Mod i f i ca t i on ] ) ,NONE( ) ) ; }

543

545 e a c h p r e f i x : EACH { $$ [ Each]= Absyn .EACH( ) ; }| /∗ empty ∗/ { $$ [ Each]= Absyn .NON EACH( ) ; }

547redec la rekeywords : REDECLARE { $$ [ RedeclareKeywords ] = Absyn .

REDECLARE( ) ; }549 | REPLACEABLE { $$ [ RedeclareKeywords ] =

Absyn .REPLACEABLE( ) ; }| REDECLARE REPLACEABLE { $$ [

RedeclareKeywords ] = Absyn .REDECLARE REPLACEABLE( ) ; }

551inne rou t e r : INNER { $$ [ InnerOuter ] = Absyn .

INNER( ) ; }553 | T OUTER { $$ [ InnerOuter ] = Absyn .OUTER( ) ;

}| INNER T OUTER { $$ [ InnerOuter ] = Absyn .

INNER OUTER( ) ; }555 // | /∗ empty ∗/ { $$ [ InnerOuter ] = Absyn .

NOT INNER OUTER( ) ; }

557importe lementspec : import comment { $$ [ ElementSpec ] = Absyn

.IMPORT( $1 [ Import ] ,SOME( $2 [ Comment ] ) , i n f o ) ; }559

c l a s s e l e me nt s pe c : class { $$ [ ElementSpec ] = Absyn .CLASSDEF(false , $1 [ Class ] ) ; }

561 | REPLACEABLE class { $$ [ ElementSpec ] =Absyn .CLASSDEF( true , $2 [ Class ] ) ; }

563 import : IMPORT path { $$ [ Import ] = Absyn .QUAL IMPORT( $2 [ Path ] ) ; }

| IMPORT path STAR EW { $$ [ Import ] = Absyn .UNQUAL IMPORT( $2 [ Path ] ) ; }

Page 216: OMCCp: A MetaModelica Based Parser Generator Applied to ...

196 APPENDIX F. MODELICA GRAMMAR

565 | IMPORT ident EQUALS path { $$ [ Import ] =Absyn .NAMED IMPORT( $2 [ Ident ] , $4 [ Path ] ) ;}

567 extends : EXTENDS path{ $$ [ ElementSpec ] = Absyn .EXTENDS( $2 [ Path

] ,{} ,NONE( ) ) ; }569 | EXTENDS path annotat ion

{ $$ [ ElementSpec ] = Absyn .EXTENDS( $2 [ Path] ,{} ,SOME( $3 [ Annotation ] ) ) ; }

571 | EXTENDS path LPAR argument l i s t RPAR{ $$ [ ElementSpec ] = Absyn .EXTENDS( $2 [ Path

] , $4 [ ElementArgs ] ,NONE( ) ) ; }573 | EXTENDS path LPAR argument l i s t RPAR

annotat ion{ $$ [ ElementSpec ] = Absyn .EXTENDS( $2 [ Path

] , $4 [ ElementArgs ] ,SOME( $3 [ Annotation] ) ) ; }

575e lementspec : e lementAttr typespec componentitems //

arraydim from typespec should be in elementAttr arraydim577 { ( $1 [ ElementAttr ibutes ] , $2 [ TypeSpec ] ) =

f ixArray ( $1 [ ElementAttr ibutes ] , $2 [TypeSpec ] ) ;

$$ [ ElementSpec ] = Absyn .COMPONENTS( $1 [ElementAttr ibutes ] , $2 [ TypeSpec ] , $3[ ComponentItems ] ) ; }

579 | typespec componentitems // arraydimfrom typespec should be in elementAttr

arraydim{ ( v1ElementAttr ibutes , $1 [ TypeSpec ] ) =

f ixArray ( Absyn .ATTR( false , false ,Absyn .VAR( ) , Absyn . BIDIR ( ) ,{} ) , $1 [TypeSpec ] ) ;

581 $$ [ ElementSpec ] = Absyn .COMPONENTS(v1ElementAttr ibutes , $1 [ TypeSpec ] , $2[ ComponentItems ] ) ; }

583 elementAttr : d i r e c t i o n{ $$ [ ElementAttr ibutes ] = Absyn .ATTR(

false , false , Absyn .VAR( ) , $1 [D i r e c t i on ] , { } ) ; }

585 | v a r i a b i l i t y{ $$ [ ElementAttr ibutes ] = Absyn .ATTR(

false , false , $1 [ V a r i a b i l i t y ] , Absyn .BIDIR ( ) ,{} ) ; }

587 | v a r i a b i l i t y d i r e c t i o n{ $$ [ ElementAttr ibutes ] = Absyn .ATTR(

false , false , $1 [ V a r i a b i l i t y ] , $2 [D i r e c t i on ] , { } ) ; }

589 | STREAM v a r i a b i l i t y d i r e c t i o n{ $$ [ ElementAttr ibutes ] = Absyn .ATTR(

false , true , $2 [ V a r i a b i l i t y ] , $3 [D i r e c t i on ] , { } ) ; }

591 | FLOW v a r i a b i l i t y d i r e c t i o n{ $$ [ ElementAttr ibutes ] = Absyn .ATTR(

true , false , $2 [ V a r i a b i l i t y ] , $3 [

Page 217: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.2. PARSERMODELICA.Y 197

Dir e c t i on ] , { } ) ; }593 | FLOW

{ $$ [ ElementAttr ibutes ] = Absyn .ATTR(true , false , Absyn .VAR( ) , Absyn . BIDIR( ) ,{} ) ; }

595

597 v a r i a b i l i t y : PARAMETER { $$ [ V a r i a b i l i t y ] = Absyn .PARAM( ) ; }

| CONSTANT { $$ [ V a r i a b i l i t y ] = Absyn .CONST( ) ; }

599 | DISCRETE { $$ [ V a r i a b i l i t y ] = Absyn .DISCRETE( ) ; }

// | /∗ empty ∗/ { $$ [ V a r i a b i l i t y ] = Absyn .VAR( ) ; }

601d i r e c t i o n : T INPUT { $$ [ D i r e c t i on ] = Absyn . INPUT( ) ; }

603 | T OUTPUT { $$ [ D i r e c t i on ] = Absyn .OUTPUT( ); }

// | /∗ empty ∗/ { $$ [ D i r e c t i on ] = Absyn .BIDIR ( ) ; }

605/∗ Type s p e c i f i c a t i o n ∗/

607typespec : path a r raySubsc r i p t s { $$ [ TypeSpec ] =

Absyn .TPATH( $1 [ Path ] ,SOME( $2 [ ArrayDim ] ) ) ; }609 | path arrayComplex { $$ [ TypeSpec ] = Absyn .

TCOMPLEX( $1 [ Path ] , $2 [ TypeSpecs ] ,NONE( ) ); }

611 arrayComplex : LESS typespecs GREATER { $$ [ TypeSpecs ] =$1 [ TypeSpecs ] ; }

613 typespecs : typespec { $$ [ TypeSpecs ] = $1 [ TypeSpec] : : { } ; }

| typespec COMMA typespecs { $$ [ TypeSpecs ]= $1 [ TypeSpec ] : : $2 [ TypeSpecs ] ; }

615a r raySubsc r i p t s : LBRACK arrayDim RBRACK { $$ [ ArrayDim ] = $1

[ ArrayDim ] ; }617 | /∗ empty ∗/ { $$ [ ArrayDim ] = {} ; }

619 arrayDim : s u b s c r i p t { $$ [ ArrayDim ] = $1 [Subsc r ip t ] : : { } ; }

| s u b s c r i p t COMMA arrayDim { $$ [ ArrayDim ] =$1 [ Subsc r ip t ] : : $2 [ ArrayDim ] ; }

621s u b s c r i p t : exp { $$ [ Subsc r ip t ] = Absyn .SUBSCRIPT( $1 [

Exp ] ) ; }623 | COLON { $$ [ Subsc r ip t ] = Absyn .NOSUB( ) ; }

625 /∗ f unc t i on c a l l s ∗/

627 f u n c t i o n c a l l : LPAR f u n c t i o n a r g s RPAR { $$ [ FunctionArgs ]= $1 [ FunctionArgs ] ; }

629 f u n c t i o n a r g s : namedargs

Page 218: OMCCp: A MetaModelica Based Parser Generator Applied to ...

198 APPENDIX F. MODELICA GRAMMAR

{ $$ [ FunctionArgs ] = Absyn .FUNCTIONARGS({} , $1 [ NamedArgs ] ) ; }

631 | f unc t i ona rg s2 { $$ [ FunctionArgs ]= $1 [FunctionArgs ] ; }

633func t i ona rg s2 : f unc t i ona rg s3 { $$ [ FunctionArgs ]= $1 [

FunctionArgs ] ; }635 | e x p l i s t 2

{ $$ [ FunctionArgs ] = Absyn .FUNCTIONARGS($1 [ Exps ] , { } ) ; }

637 | e x p l i s t 2 COMMA namedargs // TODO: Test f o rLALR grammar , may not work s h i f t / reducec o n f l i c t

{ $$ [ FunctionArgs ] = Absyn .FUNCTIONARGS($1 [ Exps ] , $2 [ NamedArgs ] ) ; }

639

641 func t i ona rg s3 : exp FOR f o r i t e r a t o r s{ $$ [ FunctionArgs ] = Absyn .FOR ITER FARG(

$1 [ Exp ] , $3 [ F o r I t e r a t o r s ] ) ; }643

645 namedargs : namedarg { $$ [ NamedArgs ] = $1 [ NamedArg] : : { } ; }

| namedarg COMMA namedargs { $$ [ NamedArgs ]= $1 [ NamedArg ] : : $2 [ NamedArgs ] ; }

647

649 namedarg : ident EQUALS exp { $$ [ NamedArg ] = Absyn .NAMEDARG( $1 [ Ident ] , $2 [ Exp ] ) ; }

651 /∗ e x p r e s s i o n s ∗/

653 exp : simpleExp { $$ [ Exp ] =$1 [ Exp ] ; }

| i f e x p { $$ [ Exp ] = $1 [ Exp ] ; }655 | matchcont { $$ [ Exp ] = $1 [ Exp ] ; }

657 matchcont : MATCH exp ca s e s ENDMATCH { $$ [ Exp ] = Absyn .MATCHEXP( Absyn .MATCH( ) , $2 [ Exp ] ,{} , $3 [ Cases ] ,NONE( ) ) ; }

| MATCH exp matchloca l c a s e s ENDMATCH { $$ [ Exp ]= Absyn .MATCHEXP( Absyn .MATCH( ) , $2 [ Exp ] , $3 [

ElementItems ] , $4 [ Cases ] ,NONE( ) ) ; }659 | MATCHCONTINUE exp ca s e s ENDMATCHCONTINUE { $$

[ Exp ] = Absyn .MATCHEXP( Absyn .MATCHCONTINUE( ) , $2 [ Exp ] ,{} , $3 [ Cases ] ,NONE( ) ) ; }

| MATCHCONTINUE exp matchloca l ca s e sENDMATCHCONTINUE { $$ [ Exp ] = Absyn .MATCHEXP( Absyn .MATCHCONTINUE( ) , $2 [ Exp ] , $3 [ElementItems ] , $4 [ Cases ] ,NONE( ) ) ; }

661

663 i f e x p : IF exp THEN exp ELSE exp { $$ [ Exp ] = Absyn .IFEXP( $2 [ Exp ] , $4 [ Exp ] , $6 [ Exp ] , { } ) ; }

| IF exp THEN exp e x p e l s e i f s ELSE exp { $$ [ Exp] = Absyn . IFEXP( $2 [ Exp ] , $4 [ Exp ] , $7 [ Exp ] , $5 [

Page 219: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.2. PARSERMODELICA.Y 199

ExpEl s e i f s ] ) ; }665

e x p e l s e i f s : e x p e l s e i f { $$ [ ExpEl s e i f s ] = $1 [ ExpEl se i f] : : { } ; }

667 | e x p e l s e i f e x p e l s e i f s { $$ [ ExpEl s e i f s ] = $1 [ExpEl se i f ] : : $2 [ ExpEl s e i f s ] ; }

669 e x p e l s e i f : ELSEIF exp THEN exp { $$ [ ExpEl se i f ] = ( $2 [ Exp] , $4 [ Exp ] ) ; }

671matchloca l : LOCAL elementItems { $$ [ ElementItems ] = $1 [

ElementItems ] ; }673

ca s e s : case { $$ [ Cases ] = $1 [ Case ] : : { } ; }675 | case ca s e s { $$ [ Cases ] = $1 [ Case ] : : $2 [ Cases

] ; }

677 case : CASE casearg THEN exp SEMICOLON{ $$ [ Case ] = Absyn .CASE( $2 [ Exp ] , in fo

,{} ,{} , $4 [ Exp ] , in fo ,NONE( ) , i n f o ) ; }679 | CASE casearg EQUATION THEN exp SEMICOLON

{ $$ [ Case ] = Absyn .CASE( $2 [ Exp ] , in fo,{} ,{} , $4 [ Exp ] , in fo ,NONE( ) , i n f o ) ; }

681 | CASE casearg EQUATION e q u a t i o n s e c t i o n THENexp SEMICOLON{ $$ [ Case ] = Absyn .CASE( $2 [ Exp ] , in fo ,{} ,

$4 [ EquationItems ] , $6 [ Exp ] , in fo ,NONE( ), i n f o ) ; }

683 | ELSE THEN exp SEMICOLON{ $$ [ Case ] = Absyn .ELSE({} ,{} , $3 [ Exp ] ,

in fo ,NONE( ) , i n f o ) ; }685 | ELSE EQUATION e q u a t i o n s e c t i o n THEN exp

SEMICOLON{ $$ [ Case ] = Absyn .ELSE({} , $3 [

EquationItems ] , $5 [ Exp ] , in fo ,NONE( ) ,i n f o ) ; }

687casearg : exp { $$ [ Exp ] = $1 [ Exp ] ; }

689

691 simpleExp : l o g i c e x p { $$ [ Exp ] = $1 [ Exp ] ; }| rangeExp { $$ [ Exp ] = $1 [ Exp ] ; }

693 | h e a d t a i l { $$ [ Exp ] = $1 [ Exp ] ; }| i d ent AS simpleExp { $$ [ Exp ] = Absyn .AS( $1 [

Ident ] , $2 [ Exp ] ) ; }695

h e a d t a i l : l o g i c e x p COLONCOLON l o g i c e x p { $$ [ Exp ] = Absyn.CONS( $1 [ Exp ] , $3 [ Exp ] ) ; }

697 | l o g i c e x p COLONCOLON h e a d t a i l { $$ [ Exp ] =Absyn .CONS( $1 [ Exp ] , $3 [ Exp ] ) ; }

699 rangeExp : l o g i c e x p COLON l o g i c e x p { $$ [ Exp ] = Absyn .RANGE( $1 [ Exp ] ,NONE( ) , $3 [ Exp ] ) ; }

| l o g i c e x p COLON l o g i c e x p COLON l o g i c e x p { $$ [Exp ] = Absyn .RANGE( $1 [ Exp ] ,SOME( $3 [ Exp ] ) ,$5 [ Exp ] ) ; }

Page 220: OMCCp: A MetaModelica Based Parser Generator Applied to ...

200 APPENDIX F. MODELICA GRAMMAR

701l o g i c e x p : l og i c t e rm { $$ [ Exp ] = $1 [ Exp ] ; }

703 | l o g i c e x p T OR log i c t e rm { $$ [ Exp ] = Absyn .LBINARY( $1 [ Exp ] , Absyn .OR( ) , $2 [ Exp ] ) ; }

705 l og i c t e rm : l o g f a c t o r { $$ [ Exp ] = $1 [ Exp ] ; }| l o g i c t e rm T AND l o g f a c t o r { $$ [ Exp ] =

Absyn .LBINARY( $1 [ Exp ] , Absyn .AND( ) , $2 [ Exp] ) ; }

707l o g f a c t o r : r e l t e rm { $$ [ Exp ] = $1 [ Exp ] ; }

709 | T NOT re l t e rm { $$ [ Exp ] = Absyn .LUNARY(Absyn .NOT( ) , $1 [ Exp ] ) ; }

711 re l t e rm : addterm { $$ [ Exp ] = $1 [ Exp ] ; }| addterm re lOperator addterm { $$ [ Exp ] =

Absyn .RELATION( $1 [ Exp ] , $2 [ Operator ] , $3 [Exp ] ) ; }

713addterm : term { $$ [ Exp ] = $1 [ Exp ] ; }

715 | unoperator term { $$ [ Exp ] = Absyn .UNARY($1 [ Operator ] , $2 [ Exp ] ) ; }

| addterm woperator term { $$ [ Exp ] = Absyn .BINARY( $1 [ Exp ] , $2 [ Operator ] , $3 [ Exp ] ) ; }

717term : f a c t o r { $$ [ Exp ] = $1 [ Exp ] ; }

719 | term sope ra to r f a c t o r{ $$ [ Exp ] = Absyn .

BINARY( $1 [ Exp ] , $2 [Operator ] , $3 [ Exp ] ) ;}

721 f a c t o r : expElement { $$ [ Exp ] = $1 [ Exp ] ; }| expElement power

f a c t o r { $$ [ Exp ] =Absyn .BINARY( $1 [ Exp] , $2 [ Operator ] , $3 [Exp ] ) ; }

723expElement : number { $$ [ Exp ] = $1 [ Exp ] ; }

725 | c r e f { $$ [ Exp ] = Absyn .CREF( $1 [ComponentRef ] ) ; }

| T FALSE { $$ [ Exp ] = Absyn .BOOL( fa l se ) ; }727 | T TRUE { $$ [ Exp ] = Absyn .BOOL( true ) ; }

| s t r i n g { $$ [ Exp ] = Absyn .STRING( $1 ) ; }729 | tup l e { $$ [ Exp ] = $1 [ Exp ] ; }

| LBRACE e x p l i s t 2 RBRACE { $$ [ Exp ] = Absyn .ARRAY( $2 [ Exps ] ) ; }

731 | LBRACK matrix RBRACK { $$ [ Exp ] = Absyn .MATRIX( $2 [ Matrix ] ) ; }

| c r e f f u n c t i o n c a l l { $$ [ Exp ] = Absyn .CALL($1 [ ComponentRef ] , $2 [ FunctionArgs ] ) ; }

733 | DER f u n c t i o n c a l l { $$ [ Exp ] = Absyn .CALL(Absyn .CREF IDENT( ” der ” ,{} ) , $2 [FunctionArgs ] ) ; }

| LPAR exp RPAR { $$ [ Exp ] = $2 [ Exp ] ; }735 | T END { $$ [ Exp ] = Absyn .END( ) ; }

Page 221: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.2. PARSERMODELICA.Y 201

737 number : UNSIGNED INTEGER { $$ [ Exp ] = Absyn .INTEGER(s t r i n g I n t ( $1 ) ) ; }

| UNSIGNED REAL { $$ [ Exp ] = Absyn .REAL(s t r i n g R e a l ( $1 ) ) ; }

739matrix : e x p l i s t 2 { $$ [ Matrix ] = {$1 [ Exps ] } ; }

741 | e x p l i s t 2 SEMICOLON matrix { $$ [ Matrix ] =$1 [ Exps ] : : $3 [ Matrix ] ; }

743 tup l e : LPAR e x p l i s t RPAR { $$ [ Exp ] = Absyn .TUPLE($2 [ Exps ] ) ; }

745 e x p l i s t : exp COMMA exp { $$ [ Exps ] = {$1 [ Exp ] , $3 [ Exp] } ; }

| exp COMMA e x p l i s t { $$ [ Exps ] = $1 [ Exp ] : : $3[ Exps ] ; }

747 | /∗ empty ∗/ { $$ [ Exps ] = {} ; }

749 e x p l i s t 2 : exp { $$ [ Exps ] = {$1 [ Exp ] } ; }| exp COMMA e x p l i s t 2 { $$ [ Exps ] = $1 [ Exp ] : :

$3 [ Exps ] ; }751 | /∗ empty ∗/ { $$ [ Exps ] = {} ; }

753 c r e f : i dent a r raySubsc r i p t s { $$ [ ComponentRef ]= Absyn .CREF IDENT( $1 [ Ident ] , $2 [ ArrayDim ] ) ; }

| i dent DOT c r e f { $$ [ ComponentRef ] =Absyn .CREF QUAL( $1 [ Ident ] ,{} , $3 [ComponentRef ] ) ; }

755 | DOT c r e f { $$ [ ComponentRef ] = Absyn .CREF FULLYQUALIFIED( $2 [ ComponentRef ] ) ;}

| WILD { $$ [ ComponentRef ] = Absyn .WILD( ) ;}757 | ALLWILD { $$ [ ComponentRef ] = Absyn .

ALLWILD( ) ;}

759 unoperator : PLUS { $$ [ Operator ] = Absyn .UPLUS( ) ; }| MINUS { $$ [ Operator ] = Absyn .UMINUS( ) ; }

761 | PLUS EW { $$ [ Operator ] = Absyn .UPLUS EW( ) ; }

| MINUS EW { $$ [ Operator ] = Absyn .UMINUS EW( ) ; }

763

765 woperator : PLUS { $$ [ Operator ] = Absyn .ADD( ) ; }

| MINUS { $$ [ Operator ] = Absyn .SUB( ) ; }767 | PLUS EW { $$ [ Operator ] = Absyn .ADD EW( ) ;

}| MINUS EW { $$ [ Operator ] = Absyn .SUB EW( ) ;

}769

771 sope ra to r : STAR { $$ [ Operator ] = Absyn .MUL( ) ; }

| SLASH { $$ [ Operator ] = Absyn . DIV( ) ; }

Page 222: OMCCp: A MetaModelica Based Parser Generator Applied to ...

202 APPENDIX F. MODELICA GRAMMAR

773 | STAR EW { $$ [ Operator ] = Absyn .MUL EW( ) ;}

| SLASH EW { $$ [ Operator ] = Absyn .DIV EW( ) ;}

775power : POWER { $$ [ Operator ] = Absyn .POW( ) ; }

777 | POWEREW { $$ [ Operator ] = Absyn .POWEW( ) ;}

779 re lOperato r : LESS { $$ [ Operator ] = Absyn .LESS( ) ; }

| LESSEQ { $$ [ Operator ] = Absyn .LESSEQ( ) ; }781 | GREATER { $$ [ Operator ] = Absyn .GREATER( ) ;

}| GREATEREQ { $$ [ Operator ] = Absyn .

GREATEREQ( ) ; }783 | EQEQ { $$ [ Operator ] = Absyn .EQUAL( ) ; }

| LESSGT { $$ [ Operator ] = Absyn .NEQUAL( ) ; }785

path : ident { $$ [ Path ] = Absyn .IDENT( $1 [ Ident ] ); }

787 | i d ent DOT path { $$ [ Path ] = Absyn .QUALIFIED( $1 [ Ident ] , $2 [ Path ] ) ; }

| DOT path { $$ [ Path ] = Absyn .FULLYQUALIFIED( $2 [ Path ] ) ; }

789ident : IDENT { $$ [ Ident ] = $1 ; }

791s t r i n g : STRING { $$ = tr imquotes ( $1 ) ; } // trim

the quote o f the s t r i n g793

comment : s t r i n g { $$ [ Comment ] = Absyn .COMMENT(NONE( ) ,SOME( $1 ) ) ; }

795 | /∗ empty ∗/ { $$ [ Comment ] = Absyn .COMMENT(NONE( ) ,NONE( ) ) ; }

797%%

799public function t r imquotes

801 ”removes chars in charsToRemove from i n S t r i n g ”input String i n S t r i n g ;

803 output String outSt r ing ;algorithm

805 i f ( s t r ingLength ( i n S t r i n g )>2) thenoutSt r ing := System . s u b s t r i n g ( inSt r ing , 2 , s t r ingLength (

i n S t r i n g )−1) ;807 else

outSt r ing := ”” ;809 end i f ;

end t r imquotes ;811

function f i xArray813 input ElementAttr ibutes v1ElementAttr ibutes ;

input TypeSpec v2TypeSpec ;815 output ElementAttr ibutes v1ElementAttr ibutes2 ;

output TypeSpec v2TypeSpec2 ;

Page 223: OMCCp: A MetaModelica Based Parser Generator Applied to ...

F.2. PARSERMODELICA.Y 203

817 Boolean f l owPre f i x , b1 , b2 ” f low ” ;Boolean s t reamPre f ix ” stream ” ;

819 // Boolean i n n e r ” inner ” ;// Boolean out e r ” outer ” ;

821 V a r i a b i l i t y v a r i a b i l i t y , v1 ” v a r i a b i l i t y ; parameter ,constant e t c . ” ;

D i r e c t i on d i r e c t i o n , d1 ” d i r e c t i o n ” ;823 ArrayDim arrayDim , a1 ”arrayDim” ;

Path path , p1 ;825 Option<ArrayDim> oa1 ;

algorithm827 Absyn .ATTR( f l o w P r e f i x=b1 , s t reamPre f ix=b2 , v a r i a b i l i t y=v1 ,

d i r e c t i o n=d1 ) := v1ElementAttr ibutes ;

829 Absyn .TPATH( path=p1 , arrayDim=oa1 ) :=v2TypeSpec ;

831 a1 := match oa1local ArrayDim l 1 ;

833 case SOME( l 1 )then ( l 1 ) ;

835 case NONE( ) then ({} ) ;end match ;

837v1ElementAttr ibutes2 := Absyn .ATTR( b1 , b2 , v1 , d1 , a1 ) ;

839 v2TypeSpec2 := Absyn .TPATH( p1 ,NONE( ) ) ;

841 end f i xArray ;

843 function pr intContentStackinput AstStack astStk ;

845 l i s t<Token> skToken ;l i s t<Path> skPath ;

847 l i s t<ClassDef> skClassDef ;l i s t<Ident> skIdent ;

849 l i s t<Class> skClass ;l i s t<Program> skProgram ;

851 l i s t<l s t C l a s s > s k l s t C l a s s ;l i s t<String> skS t r ing ;

853 l i s t<Integer> s k I n t e g e r ;algorithm

855 ASTSTACK( stackToken=skToken , stackPath=skPath , s tackClas sDe f=skClassDef , s tack Ident=skIdent , s t ackCla s s=skClass ,stackProgram=skProgram , s t a c k l s t C l a s s=s k l s t C l a s s , s t a c k S t r i n g=skStr ing , s t a c k I n t e g e r=s k I n t e g e r ) := astStk ;

857 print ( ”\n Stack content : ” ) ;print ( ” skToken : ” ) ;

859 print ( intString ( l i s t L e n g t h ( skToken ) ) ) ;print ( ” skPath : ” ) ;

861 print ( intString ( l i s t L e n g t h ( skPath ) ) ) ;print ( ” skClassDef : ” ) ;

863 print ( intString ( l i s t L e n g t h ( skClassDef ) ) ) ;print ( ” skIdent : ” ) ;

865 print ( intString ( l i s t L e n g t h ( skIdent ) ) ) ;print ( ” skClass : ” ) ;

867 print ( intString ( l i s t L e n g t h ( skClas s ) ) ) ;print ( ” skProgram : ” ) ;

Page 224: OMCCp: A MetaModelica Based Parser Generator Applied to ...

204 APPENDIX F. MODELICA GRAMMAR

869 print ( intString ( l i s t L e n g t h ( skProgram ) ) ) ;print ( ” s k l s t C l a s s : ” ) ;

871 print ( intString ( l i s t L e n g t h ( s k l s t C l a s s ) ) ) ;print ( ” skSt r ing : ” ) ;

873 print ( intString ( l i s t L e n g t h ( skSt r ing ) ) ) ;print ( ” s k I n t e g e r : ” ) ;

875 print ( intString ( l i s t L e n g t h ( s k I n t e g e r ) ) ) ;end pr intContentStack ;

Page 225: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Appendix G

Additional Files

G.1 SCRIPT.mos

Listing G.1: SCRIPT.mos

2 // setCommandLineOptions({”+g=MetaModelica” ,”+d=rml , noeva l func ”});

g e t I n s t a l l a t i o n D i r e c t o r y P a t h ( ) ;4 // setCommandLineOptions(”+g=MetaModelica” ,”+d=rml , noeva l func ”) ;

6 l o a d F i l e ( ”Types .mo” ) ;l o a d F i l e ( ” . . / . . / Compiler /FrontEnd/Absyn .mo” ) ;

8 l o a d F i l e ( ” . . / . . / Compiler / U t i l / Error .mo” ) ;l o a d F i l e ( ” . . / . . / Compiler / U t i l / ErrorExt .mo” ) ;

10 l o a d F i l e ( ” . . / . . / Compiler /FrontEnd/Dump.mo” ) ;l o a d F i l e ( ” . . / . . / Compiler / U t i l / Pr int .mo” ) ;

12 l o a d F i l e ( ” . . / . . / Compiler / U t i l /RTOpts .mo” ) ;l o a d F i l e ( ” . . / . . / Compiler / U t i l / U t i l .mo” ) ;

14 l o a d F i l e ( ” . . / . . / Compiler / U t i l /System .mo” ) ;

16 l o a d F i l e ( ”TokenModelica .mo” ) ;l o a d F i l e ( ” LexTableModelica .mo” ) ;

18 l o a d F i l e ( ” LexerCodeModelica .mo” ) ;l o a d F i l e ( ” LexerModel ica .mo” ) ;

20 l o a d F i l e ( ” ParseCodeModelica .mo” ) ;l o a d F i l e ( ” ParserModel ica .mo” ) ;

22 l o a d F i l e ( ” ParseTableModel ica .mo” ) ;

24 l o a d F i l e ( ”Main .mo” ) ;

26 // l o a d F i l e (” Program .mo”) ;

28//Main . main ({”” ,”10”} ) ;

30 //Main . main ({”” ,”4”} ) ;//Main . main ({” program .mo” ,”10”}) ;

32 Main . main ({ ”TestGrammar .mo” , ” Modelica ” }) ;

205

Page 226: OMCCp: A MetaModelica Based Parser Generator Applied to ...

206 APPENDIX G. ADDITIONAL FILES

//Main . main ({” Absyn .mo” ,” Modelica ”}) ;34 /∗Main . main ({” ParserGenerator .mo” ,” Modelica ”}) ;

Main . main ({” LexerGenerator .mo” ,” Modelica ”}) ;36 Main . main ({” ParserModel ica .mo” ,” Modelica ”}) ;

Main . main ({” LexerModel ica .mo” ,” Modelica ”}) ;38 Main . main ({” LexTableModelica .mo” ,” Modelica ”}) ;

Main . main ({” LexerCodeModelica .mo” ,” Modelica ”}) ;40 Main . main ({” ParserModel ica .mo” ,” Modelica ”}) ;

Main . main ({” ParseCodeModelica .mo” ,” Modelica ”}) ;42 Main . main ({” ParseTableModel ica .mo” ,” Modelica ”}) ;

Main . main ({” TokenModelica .mo” ,” Modelica ”}) ; ∗/44 //Main . main ({” program4 . txt ” ,”4”}) ;

g e tEr ro rS t r i ng ( ) ;

G.2 Main.mo

Listing G.2: Main.mo

1 class Main

3 import Lexer ;import Parser ;

5import LexerModel ica ;

7 import ParserModel ica ;

9 import Util ;import RTOpts ;

11 import System ;import Types ;

13

15 public function main” func t i on : main

17 This i s the main func t i on that the MetaModelica Compiler (MMC)runtime system c a l l s to

s t a r t the t r a n s l a t i o n . ”19 input l i s t<String> i n S t r i n g L s t ;

l i s t<OMCCTypes . Token> tokens ;21 ParserModel ica . AstTree astTreeModel ica ;

type Mcode MCodeLst = l i s t<Mcode . MCode>;23 algorithm

25:= matchcontinue ( i n S t r i n g L s t )

27 localString v e r s t r , e r r s t r , f i l ename , parser , a s t ;

29 l i s t<String> args 1 , args , chars ;String s , s t r , omhome , oldpath , newpath , unparsed ;

31 Boolean r e s u l t ;Real t l , tp , t t ;

33 case args as : :equation

35 { f i l ename , pa r s e r } = RTOpts . args ( args ) ;

Page 227: OMCCp: A MetaModelica Based Parser Generator Applied to ...

G.2. MAIN.MO 207

37 ” Modelica ” = par s e r ;fa l se=(0==str ingLength ( f i l ename ) ) ;

39 print ( ”\nParsing Modelica with f i l e ” + f i l ename + ”\n”) ;

41 // c a l l the l e x e r// tokens = LexerModel ica . s canSt r ing (” He l lo ” , t rue ) ;

43 System . s tartTimer ( ) ;tokens = LexerModel ica . scan ( f i l ename , fa l se ) ;

45 System . stopTimer ( ) ;t l = System . getTimerIntervalTime ( ) ;

47 print ( ”\n Time Lexer : ” + r e a l S t r i n g ( t l ) ) ;// p r i n t (OMCCTypes . pr intTokens ( tokens , ” ” ) ) ;

49 print ( ”\n Tokens proce s s ed : ” ) ;print ( intString ( l i s t L e n g t h ( tokens ) ) ) ;

51 // c a l l the par s e r

53 System . s tartTimer ( ) ;( r e s u l t , astTreeModel ica ) = ParserModel ica . parse (

tokens , f i l ename , fa l se ) ;55 System . stopTimer ( ) ;

// p r i n t ( s t r : : a r g s 1 ) ;57 tp = System . getTimerIntervalTime ( ) ;

print ( ”\n Time Parser : ” + r e a l S t r i n g ( tp ) ) ;59 t t = t l+tp ;

print ( ”\n TOTAL Time : ” + r e a l S t r i n g ( t t ) ) ;61 print ( ”\n” ) ;

// p r i n t the AST63 i f ( r e s u l t ) then

// unparsed = Dump. unparseStr ( astTreeModel ica , f a l s e );

65 // p r i n t ( unparsed ) ;print ( ”\nSUCCEED” ) ;

67 System . w r i t e F i l e ( ”UnParsed” + f i l ename ,Dump.unparseStr ( astTreeModel ica , true ) ) ;

// printAny ( unparsed ) ;69 else

// p r in t ( Error . getMessagesStr ( ) ) ;71 print ( ”\n” +Error . pr intMessagesStr ( ) ) ;

end i f ;73 // Run the machine f o r e x e r c i s e 10

75

77 // printAny ( astTree ) ;print ( ”\nargs : ” + f i l ename ) ;

79pr intUsage ( ) ;

81 then ( ) ;case {}

83 equationprint ( ”no args ” ) ;

85 pr intUsage ( ) ;then ( ) ;

87 caseequation

Page 228: OMCCp: A MetaModelica Based Parser Generator Applied to ...

208 APPENDIX G. ADDITIONAL FILES

89 print ( ”\n∗∗∗∗∗∗∗∗∗∗Error ∗∗∗∗∗∗∗∗∗∗∗∗∗” ) ;pr intUsage ( ) ;

91 then ( ) ;end matchcontinue ;

93 end main ;

95 public function pr intUsageInteger n ;

97 Lis t<String> s t r s ;algorithm

99 print ( ”\nOMCC v0 . 9 . 2 ( OpenModelica Compiler− Compiler ) Lexerand Parser Generator − 2011” ) ;

end pr intUsage ;101

protected function r e ad Se t t i ng s103 ” func t i on : r e a dS e t t i ng s

author : x02lucpo105 Checks i f ’ s e t t i n g s . mos ’ e x i s t and uses handleCommand with

runScr ip t ( . . . ) to execute i t .Checks i f ’− s < f i l e >.mos ’ has been

107 r e tu rn s I n t e r a c t i v e . Interact iveSymbolTable which i s used in ther e s t o f the loop ”

input l i s t<String> i n S t r i n g L s t ;109 output String s t r ;

algorithm111 s t r :=

matchcontinue ( i n S t r i n g L s t )113 local

l i s t<String> args ;115 case ( args )

equation117 outSymbolTable = I n t e r a c t i v e . emptySymboltable ;

”” = Util . f l agVa lue ( ”−s ” , a rgs ) ;119 // t h i s i s out−commented because automat i ca l l y read ing

s e t t i n g s . mos// can make a system bad

121 // outSymbolTable = r e a d S e t t i n g s F i l e (” s e t t i n g s . mos” ,I n t e r a c t i v e . emptySymboltable ) ;

then123 outSymbolTable ;

case ( args )125 equation

s t r = Util . f l agVa lue ( ”−s ” , a rgs ) ;127 s t r = System . tr im ( s t r , ” \”” ) ;

outSymbolTable = r e a d S e t t i n g s F i l e ( s t r , I n t e r a c t i v e .emptySymboltable ) ;

129 thenoutSymbolTable ;

131 end matchcontinue ;end r e ad Se t t i ng s ;

133

135 end Main ;

Page 229: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Glossary

Abstract Syntax Tree (AST) A data structure representing somethingwhich has been parsed, often used as a compiler or interpreter’s in-ternal representation of a program while it is being optimised andfrom which code generation is performed. The range of all possi-ble such structures is described by the abstract syntax. [Howe, 2010,http://foldoc.org/abstract+syntax+tree]. 2, 69

Backus-Naur Form BNF is a formal metasyntax used to express context-free grammars. [Howe, 2010, http://foldoc.org/Backus-Naur+Form].29

Compiler-Compiler A utility to generate the source code of a parser, in-terpreter or compiler from an annotated language description (usuallyin BNF). Most so called compiler-compilers are really just parser gen-erators. [Howe, 2010, http://foldoc.org/compiler-compiler]. 1,35

Extended Backus-Naur Form EBNF is a variation on the basic BNFmeta-syntax notation with (some of) the following additional con-structs: square brackets surrounding optional items, suffix ”*” forKleene closure (a sequence of zero or more of an item), suffix ”+” forone or more of an item, curly brackets enclosing a list of alternatives,and super/subscripts indicating between n and m occurrences [Howe,2010, http://foldoc.org/Extended+Backus-Naur+Form]. . 25

Functional Programming A program in a functional language consistsof a set of (possibly recursive) function definitions and an expressionwhose value is output as the program’s result. Functional languagesare one kind of declarative language. They are mostly based on thetyped lambda-calculus with constants. There are no side-effects to ex-pression evaluation so an expression, e.g. a function applied to certainarguments, will always evaluate to the same value (if its evaluationterminates). Furthermore, an expression can always be replaced by its

209

Page 230: OMCCp: A MetaModelica Based Parser Generator Applied to ...

210 Glossary

value without changing the overall result (referential transparency).[Howe, 2010, http://foldoc.org/functional+programming]. 46

GNU Bison Bison is a general-purpose parser generator that converts anannotated context-free grammar into an LALR(1) or GLR parser forthat grammar [Donnelly and Stallman, 2010, http://www.gnu.org/software/bison/]. 23, 28–32, 46, 48, 49, 58, 64, 65, 81

Lexer A Lexer is a program that performs the Lexical Analysis in a Com-piler.. 2, 8, 33, 35, 37, 41, 44, 53, 69

MetaModelica MetaModelica is an extension of the Modelica languagecreated with the purpose of allowing people from the Modelica commu-nity to contribute to the development of the OpenModelica compiler(OMC) [Pop and Fritzson, 2006].. 1, 5, 19, 46, 58, 64–66

Modelica Modelica is an object-oriented equation-based programming lan-guage that allows specification of mathematical models of complexnatural or man-made systems [Fritzson, 2004].. 1, 5, 18, 19, 64, 66

Parser A Parser is a program that performs the Syntax Analysis in a Com-piler.. 1, 2, 33, 39, 41, 44, 51–53, 69

UTF-8 (UCS Transformation Format 8) An 8-Bytes ASCII-compatible multi-byte Unicode and UCS encoding. [Howe, 2010, http://foldoc.org/utf-8]. 28, 35, 37, 38, 42

Page 231: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Acronyms

ANTLR Another Tool for Language Recognition. 1, 2, 23–26, 54, 62, 65,69, 70

AST Abstract Syntax Tree. 1, 7, 11, 12, 26, 29, 31, 35, 40–44, 46, 48, 49,62, 64, 70

BNF Backus-Naur Form. 25, 28, 29, 44, 209

CFG Context Free Grammar. 10

DFA Deterministic Finite Automata. 9, 10, 27, 33, 35, 37–39, 45, 46, 58

EBNF Extended Backus-Naur Form. 25, 209

FLEX Fast Lexical Analyzer Generator. 23, 28, 32–34, 44–46, 48, 58, 64,65, 67, 81

LALR Look Ahead LR parser. 12, 13, 15, 28, 30, 31, 33, 58, 67

LEX Lexical Analyzer Generator. 27, 28

LL Left to right, Left most derivation parser. 11, 12, 25

LR Left to right, Right most derivation parser. 11–13, 15, 65

NFA Non-Deterministic Finite Automata. 9

OMC OpenModelica Compiler. 1–3, 5, 23, 26, 27, 33, 34, 49, 54, 57, 61,64–66, 70

OMCCp OpenModelica Compiler-Compiler parser generator. 2, 23, 33,34, 39, 44–46, 49, 50, 54, 55, 57–59, 61, 62, 64–66, 69–71, 81

OSMC Open Source Modelica Consortium. 1, 2

PDA Push-Down Automata. 10, 11, 29, 41, 46, 49, 58

211

Page 232: OMCCp: A MetaModelica Based Parser Generator Applied to ...

212 Acronyms

SLR Simple LR parser. 12

YACC Yet Another Compiler-Compiler. 28

Page 233: OMCCp: A MetaModelica Based Parser Generator Applied to ...

Avdelning, InstitutionDivision, Department

DatumDate

Sprak

Language

� Svenska/Swedish

� Engelska/English

RapporttypReport category

� Licentiatavhandling

� Examensarbete

� C-uppsats

� D-uppsats

� Ovrig rapport

URL for elektronisk version

ISBN

ISRN

Serietitel och serienummerTitle of series, numbering

ISSN

Linkoping Studies in Science and Technology

Thesis No. LIU-IDA/LITH-EX-A–11/019–SE

TitelTitle

ForfattareAuthor

SammanfattningAbstract

NyckelordKeywords

The OpenModelica Compiler-Compiler parser generator (OMCCp) is anLALR(1) parser generator implemented in the MetaModelica language withparsing tables generated by the tools Flex and GNU Bison. The code gener-ated for the parser is in MetaModelica 2.0 language which is the OpenMod-elica compiler implementation language and is an extension of the Modelica3.2 language. OMCCp uses as input an LALR(1) grammar that specifies theModelica language. The generated Parser can be used inside the OpenMod-elica Compiler (OMC) as a replacement for the current parser generated bythe tool ANTLR from an LL(k) Modelica grammar. This report explains thedesign and implementation of this novel Lexer and Parser Generator calledOMCCp.Modelica and its extension MetaModelica are both languages used in the Open-Modelica environment. Modelica is an Object-Oriented Equation-Based lan-guage for Modeling and Simulation.

IDA,Dept. of Computer and Information Science581 83 Linkoping

2011-05-31

LIU-IDA/LITH-EX-A–11/019–SE

-

http://urn.kb.se/resolve?urn=urn:nbn:se:liu:diva-68863

2011-05-31

OMCCp: A MetaModelica Based Parser Generator Applied to Model-ica

Edgar Alonso Lopez-Rojas

××

Compiler, Parser, Lexer, Modelica, MetaModelica, OpenModelica,Simulation,LALR, Flex, Bison, Parser Generator,OMCC,OMCCp