In this lecture, the purpose and role of language based editors is discussed as well as their categorizing depending on the type of programming they facilitate and the level of language support they offer, for example. Also, linkers are discussed and their role as well as the advantages and disadvantages of dynamic linking. In addition to this, the purpose of code generators and their advantages and disadvantages are explored. Finally, the role of debugging is illustrated
Appreciate the role and various types of language based editors.
Appreciate the purpose of linkers and be familiar with the advantages and disadvantages of dynamic linking.
Appreciate the purpose, advantages, and disadvantages of code generators.
Be familiar with the role of debugging.
Editors are software tools that can be used to input and format text. Linkers are programs that take one or more objects from a collection called a library and combine them into a single executable program. Code generators take a model and translate it into code of a different, simpler language, and sometimes they generate not code but calls into external libraries. Debuggers are tools that support the software construction process. They are computer programs that are used to test and debug other programs.
The rest of the lecture is organized as follows: Section 2 presents editors. Section 3 presents linkers. Section 4 presents code generators. Finally, section 5 presents debuggers.
An editor is a software tool that can be used to input and format text. Language-based editors represent an important achievement in in software engineering technology. They enable engineers to create, browse, and modify software documents in terms of the formal languages and notations in which they are written such as statements, integer expressions, and assignments.
Program editors are also used for the creation and modification of programs, and possibly the documents associated with them. They can be general-purpose text or document editors, or they can be specialized for a given target language.
Many language-based editing systems were designed to minimize the use of keystrokes and prevent program syntax errors.
Editors when dealing with programs, they display source code for a users to read and be able to modify this source code. The technology of editors has not changed much in the last two decades, despite the intuition that specializing the technology for programming languages might increase user productivity substantially. In contrast, word processors have evolved beyond simple text editors during those same two decades.
Unfortunately, extensive research, numerous prototypes, and more than a few commercial attempts were not able to develop practical language-based editing for source code. Users, programmers, and software engineers find editors difficult and unpleasant when compared with simple text editors.
There are various types of language-based editors which can be categorized by the following:
The type of programming they facilitate, i.e. object-oriented, structured, functional.
The level of language support they offer.
The types of editing techniques they offer.
Are errors prevented or detected, or both? And is this done automatically or according to the preference of the user?
Are they able to execute only complete modules or can they execute programs which are not fully complete?
There are two requirements for editors which are often conflicting. These requirements are:
Programmers perspective: the editor must make reading and writing source code easier and more rewarding.
Tool builders perspective: the editor must reliably share information with other tools, for which it may act as a user interface, and it must be packaged for reuse (portable, highly configurable, and embeddable).
One example of program editors is the CodeProcessor which is an experimental tool for editing source code. CodeProcessor was developed by Sun Microsystems Laboratories. It has the following features:
It is based on technology that strikes a balance among competing requirements.
It is text oriented, but fundamentally driven by language technology.
It can make its language-oriented representation (configured by declarative specifications) available to other tools.
It can be embedded in other graphical user interface contexts.
It is a lexically-oriented intermediate representation for source code that addresses both usability and integration with other tools.
Features of program editors include the following:
They enhance reading and writing: This includes automatic indentation of source code lines. This service is based loosely on linguistic structure, and it helps both reading (visual feedback on nesting) and writing (saving tedious keystrokes). This particular service can be delivered in a simple text editor, but it can be taken much further.
Treatment of fragmentary and malformed source code: This is the normal state for programs under development. Unfortunately, language-based editors typically treat such situations as user errors and encourage or require corrective action.
Access to linguistic structure: Software engineering tools (for example analyzers, builders, compilers, and debuggers) generally operate over structural source code representations such as abstract syntax trees. An editing tool is most easily integrated with other tools if it can share such representations. This presents severe design challenges for a tool whose job is to display and permit modification to source code in terms of text.
In computer science, a linker is a program that collects objects from a library and places them together in one executable program as shown in Figure 1. In Figure 1, the input of the linker is object files and static libraries and the output of the linker is a new library or executable file. Not all linkers add in the whole library in its output, some linkers only include the symbols of the objects in the library as well as using and connecting other libraries as output.
In some cases, the linker is referred to as the 'loader' as well as the process that is carried out (collecting objects from libraries and placing them in one program) can also be called as 'loading' instead of linking.
Figure 1: The linker's process
Computer programs, in most cases, are made up of several parts, also known as modules. These modules need to be present in a single object file in order to be executable. The modules are also referred to as symbols, which are made up of three types:
Defined symbols: Defined symbols can be called by other modules.
Undefined symbols: Undefined symbols can call other modules (which are made up of defined symbols) but cannot be called.
Local symbols: Local symbols are responsible for the relocation of symbols between modules.
When a program contains more than one object file, it is the linkers responsibility to combine them together into one executable program, relocating the various symbols accordingly.
27.3 Dynamic Linking
Many operating system environments allow dynamic linking. Dynamic linking is a technique used for delaying the settling of the undefined symbols until the program is executed. This means that the code that is being executed will have undefined symbols, which are defined upon execution by the linker (as well as having the needed libraries).
The dynamic linker is the part of an operating system (OS) that loads and links the shared libraries for an executable when it is executed. The specific operating system and executable format determine how the dynamic linker functions and how it is implemented.
The dynamic linking approach has two advantages:
Libraries that are used repeatedly are stored only in one place and not duplicated or re-created every time they need to be used.
If an error in a library is fixed or the whole library itself is replaced then all programs that use this library will feel the effect of this without having to be re-linked again. On the other hand, if static linking was to be used, the programs have to be re-linked.
There dynamic linking approach also has the following disadvantages:
A dynamic linked library which is not compatible and has been updated may lead to errors in executable programs, which only work with the previous versions.
27.4 Code Generators
Instead of producing code by hand a tool can automatically generate it from models. Blocks in the model represent different operations, for example a mathematical or conditional operation. Signals work their way through the blocks like variables change during execution of a program. This kind of tools is called a code generator. Hence, code generators take a model and translate it into code of a different, simpler language, and where it makes sense, they generate not code but calls into external libraries.
In this context, libraries have two purposes:
They avoid code duplication
They allow us to express semantics that can't be expressed in the language's patterns
Objectives of code generation include the following:
Generate generic code for the platform instead of writing it.
Generate schematic code using transformations based on an application model.
Write individual code that is application specific.
Code generation from models has the following advantages:
Code generation is especially effective at eliminating syntax errors. Code from a specific block in the model is generated exactly the same every time.
The potential for introducing errors with manual translation is high. By using an automatic code generator, these errors are minimized and the code is kept consistent with the model design.
When generating code automatically, standardized functions, comments and documentation are created. Thus the implementation and documents are kept up to date.
Automatic code generators are valuable in maintaining consistency and eliminating the gap between design models and their implementations.
Automatic code generation increases the productivity and quality of the developed systems, enables mechanical and repetitive operations to be done quickly, reliably and uniformly, relieves designers from mundane tasks so they can focus on essence, and enforces programmers to write structured, legible code.
Code generators do the work for the programmer.
Code generators are repeatable, and the generated code will most likely work if the code generator was designed correctly.
Code generators can save a lot of time doing menial coding tasks.
Code generators promise reduced turn-around times.
Code generators separate the application logic from implementation platform details.
Code generators improve programmer productivity.
Code generators improve quality of the application due to standardized implementation.
Code generators that produce efficient code increase performance of the application that they generate.
Automated code generation is an enabling technology for model-based software development and has significant potential to improve the entire software development process.
Code generators eliminate manual coding errors.
Code generation from models has the following disadvantages:
Using a code generator does not guarantee getting error free software. The unlimited number of combinations of modeling constructs can lead to errors.
Bad modeling will also result in bad code. If the model contains logic errors, these errors will be transferred to the code.
Code generators force software engineers/programmers into writing the code that is compatible with the generated code. If the generator is good, it will allow software engineers/programmers to change functionality, but that almost always increases the complexity of the code generated etc. This complexity has a price. It's more difficult to understand, and it can be less efficient than that code you software engineers/programmers themselves.
The transition from model to code differs based on the available code generator used, but guidelines and standards regulate the outcome. Some standards are very strict and require an extensive certification process.
The move towards automating code generation is also in line with the industrial experience that the most complex task in creating a new system is modeling it at the semantic level and not in writing its detailed code.
Code generators can generate code, even when the input models or patterns are not a complete, self-sufficient system. What code generators can't express in the target language of the source code, they simply assume implemented in libraries. This is how things work. We have to build higher-order languages, languages that implement recurring patterns just the way as today's programming languages implement assembly loop patterns. Once we have such languages, we can translate them automatically into code.
Automatic code generation from models is a fairly new technology. It is becoming an
accepted and applied method when creating software.
Developing code generators is not a trivial task. This is due to the following reasons:
A good code generator should narrow the gap between the design models and their implementation. This gap exists due to differences in the abstraction level and in the perspectives adopted in the design and implementation stages.
A code generator should be flexible and applicable to various programming languages. Most of the existing code generators define rules for translating visual constructs to corresponding code blocks in a specific programming language. These language-specific rules are usually strict and reflect the insight and the style of the code generator implementers. Changing the translation rules in these tools requires massive rewriting of their code generators.
Motivations for code generators include the following:
Model-driven software development makes models a key artifact in the software engineering process.
When working with models, automation of redoing tasks can often be achieved by code generation.
The MDA approach favors code generation from models.
Architecture-centric model driven software development generates code from models.
27.5 Debugging Tools (Debuggers)
In software engineering, debugging is the process of locating and fixing or bypassing bugs (errors) in computer program code. A debugger is a computer program that is used to test and debug other programs (the target programs). Because most computer programs contain thousands of lines of code, almost any new product is likely to contain a few bugs.
Debuggers are used to support the software construction process. They identify coding errors at various development stages. Some programming language packages include a facility for checking the code for errors as it is being written.
An alternative approach to debug and examine a computer program might be to run it on an instruction set simulator (ISS), a technique that allows the stopping of the program being tested when specific conditions are encountered. Running a program in ISS mode is slower than executing it directly on the same processor. Some debuggers offer two modes of operation:
partial simulation to limit the impact of slowing down the running program
When there is an error or bug and the program malfunction, in most cases, the program crashes. When the program crashes, the debugger can establish the position of the crash in the program code.
Debuggers support the following functions:
Instead of executing the whole program, debuggers allow user to execute the program step by step.
The stopping of the execution can also be carried out, in order to monitor the state of the program at specific points.
The stopping can also allow the user to track the value of a variable in the program.
A crash can be bypassed to allow the continuation of the execution.
In this lecture, the purpose and role of language based editors is discussed as well as their categorizing depending on the type of programming they facilitate and the level of language support they offer, for example. Also, linkers are discussed and their role as well as the advantages and disadvantages of dynamic linking. In addition to this, the purpose of code generators and their advantages and disadvantages are explored. Finally, the role of debugging is illustrated.