Regular Expression | Compiler Design

Regular Expression

A regular expression is a set of patterns that can match a character or string. It can also match alternative characters or strings. The grammar defined by the regular expression is known as regular grammar, and the language is known as regular language. Any string matched by the regular expression is a set of symbols over an alphabet. The repetition and alternation in any string are expressed using *, +, and |.

In any regular expression, a* means a can occurs zero or more times. It can generate (e, aa, aaa, aaaa ...).

In any regular expression, a+ means a can occurs one or more times. It can generate (a, aa, aaa, aaaa ...).

Here are the rules that define regular expression over some alphabet and the language those expressions denote.

Let a and b are regular expressions expressing the language L(a) and L(b).

  1. (a)|(b) is a regular expression representing the language L(a) union L(b).
  2. (a)(b) is regular expression representing  the language L(a)L(b).
  3. (a)* is regular expression representing (L(a))*
  4. (a) is a regular expression representing L(r).

Operation on Regular Language

The various operations on the regular language are discussed below:

Union: If X and Y are regular expressions, L union M is also union.

X U Y = {a | a is in X or a is in Y}

Intersection: If X and Y are regular expressions, their intersection is also an intersection.

X ? Y = {ap | a is in X and p is in Y}

Kleene closure: If X is a regular language, its Kleene closure X1* will also be a regular language.

X* = the language L can occur zero or more times.

Precedence and Associativity

  • Unary operator * is left-associative and with the highest precedence.
  • Concatenation is the left-associative and has the second-highest precedence.
  • | (pipe sign) is also left-associative with the lowest precedence amongst all of them.

Example -

Let X = (a, b)

  • The regular expression a|b denote the language {a, b}.
  • (a|b)(a|b) represent {aa, ab, ba, bb} the language of all strings having length two over the alphabet X. One more regular expressions that can accept the same language is aa|ab|ba|bb.
  • a* represents the group of all strings that have zero or more a's, i.e. (e, aa, aaa, aaaa, ......).
  • (a|b)* represent the group of all strings having zero or more times of a or b, i.e., all string that contains a's and b's: {e, a, b, aa, ab, ba, bb, aaa,}. One more regular expression that accepts the same language is (a*b*)*.                                                                                                                                                  
  • a|a*b denotes the language {a, b, ab, aab, aaan ...}, i.e., the string a, and all strings have zero or more a's and ending with b.

Extensions of Regular Expressions

Kleene introduced regular expression in the 1950s with the basic operation for a union, concatenation, and Kleene closure.

Here are the few notational extension mentioned that are currently in use:

  1. One or more instance: Unary postfix operator + shows positive closure of a regular expression and its language. It stated that if a is the regular expression, then (a)+ denotes the language (L(a)+.  Two algebraic laws r* = r+|e and r+ =rr* = r*r relate the positive closure and Kleene closure.
  2. Zero or one instance: Unary postfix operator? means zero or one occurrence. It means that r? is equivalent to r|e or L(r?) = L(r) U {e}. This operator has the same precedence and associativity as * and +.

Related Topics

Switch Case Statement Compiler Design

Case Statement The “case” or “switch” statement is available in various languages. The following is the syntax for the case statement: switch (E)  {             case V1: S1             case V2: S2 ...

1 minute read.

CLR Parsing Compiler Design

CLR Parsing CLR parsing refers to the canonical lookahead. We will use the canonical collection of LR(1) items for the construction of the CLR(1) parsing table. Generally, CLR(1) parsing has more...

6 minutes read.

Machine-Independent Optimizations in Compiler Design

Machine-Independent Optimizations The main aim of machine-independent optimization is to improve the generated intermediate code so that compiler can get better target code. Eliminating unwanted code from the object code or replacing...

8 minutes read.

Storage Allocation

Storage Allocation The storage allocation represents memory management. The allocation of memory can be done in the following ways: Static AllocationStack AllocationHeap Management Static Allocation: It is a procedure used for the allocation of...

1 minute read.

Compiler Design Tutorial

Our compiler design tutorial will provide all the information about compiler from basic to advanced level. This compiler tutorial will help the student for their semester as well as for...

3 minutes read.

Errors in Compiler Design

Introduction Errors in compiler design refer to mistakes or issues that arise during the process of execution of the program. A compiler is a program that translates source code written in...

4 minutes read.

LR Parser in Compiler Design

LR Parser The most popular type of bottom-up parsing is LR(K) parsing. The LR() parser scans the input from left – to – right, which is the actual abbreviation of L...

2 minutes read.

Symbol Table Compiler Design

Symbol Table It is an important data structure used by the compiler. It stores information about various entities such as object, class, variable names, functions name, interfaces, procedure, literals, string etc.  The...

3 minutes read.

Ambiguity Elimination Compiler Design

Ambiguity Elimination Ambiguity elimination makes the sentence clear and readable. A sentence is grammatically ambiguous if it can produce more than one parse tree for a particular grammar. In this article,...

3 minutes read.

Parsing in Compiler Design

Parsing is the term used to describe the process of converting data between different formats. The parser can carry out this operation. The parser is a part of the translator...

4 minutes read.

Code Generation

Code Generation The last phase of the compiler is code generation. It is the compiler's back-end that makes multiple passes over the IR before generating the target program. The code generator's...

4 minutes read.

Target Machine

Target Machine A target machine is a byte-addressable machine. This machine has n general-purpose registers, R0, R1,.....Rn-1. A Simple Target Machine Model has three-address instruction. A full-edged assembly language would have...

3 minutes read.

LALR 1 Parsing | Compiler Design

LALR (1) Parsing The LALR parsing refers to the "lookahead LR" that has many lesser steps than typical parsers based on LR(1) items. For constructing the LALR(1) parsing table, the canonical...

6 minutes read.

Three-Address Code

Three-Address Code If there is at most one operator on the right side of the instruction, then the instruction will be the three-address code so that no arithmetic expressions are permitted....

2 minutes read.

LEX

LEX Lex is a tool/computer program that generates a Lexical analyzer. Lex is developed by Vern Paxson in C around 1987. Lex works together with the YACC parser generator. It allows...

3 minutes read.

Derivation and Parse Tree in Compiler Design

Derivation and Parse Tree In this article, we will learn Derivation and Parse Tree. Derivations The parse tree can be constructed by taking a derivational view in which production is treated as rewriting...

4 minutes read.

Optimization of Basic Blocks in Compiler Design

Optimization of Basic Blocks We can apply the optimization process on a basic block. While optimization, there is no need to change the set of expressions computed by the block. The basic...

3 minutes read.

Evolution of Programming Languages in Compiler Design

The Evolution of Programming Languages The first computer came in the 1940s and was programmed in a binary language that told the computer what operations are to be performed and in...

4 minutes read.

YACC in Compiler Design

YACC  YACC is known as Yet Another Compiler Compiler. It is used to produce the source code of the syntactic analyzer of the language produced by LALR (1) grammar. The input...

5 minutes read.

Stack Allocation of Space

Stack Allocation of Space Almost all compilers for languages that use procedure, functions, or methods manage their run-time memory as a stack. Whenever a procedure is called, the local variable's space...

2 minutes read.