Skip to main content

Components of a Programming Language

  • Chapter
  • First Online:
Domain-Specific Languages in R
  • 1256 Accesses

Abstract

While this is not a book about compilers and computer languages in general, it will be helpful to have some basic understanding of the components of software that parse and manipulate computer languages—or at least domain-specific computer languages.

This is a preview of subscription content, log in via an institution to check access.

Access this chapter

eBook
USD 19.99
Price excludes VAT (USA)
  • Available as EPUB and PDF
  • Read on any device
  • Instant download
  • Own it forever
Softcover Book
USD 27.99
Price excludes VAT (USA)
  • Compact, lightweight edition
  • Dispatched in 3 to 5 business days
  • Free shipping worldwide - see info

Tax calculation will be finalised at checkout

Purchases are for personal use only

Institutional subscriptions

Notes

  1. 1.

    Technically, what I refer to as grammar is syntax. Linguists use grammar to refer to both morphology and syntax, where syntax is the rules for stringing words together. In computer science, though, the term grammar is used as I use it here. Therefore, I will use syntax and grammar interchangeably.

  2. 2.

    The purists might complain here and say that a parser will construct a parse tree and not an AST . The difference between the two is that a parse tree contains all the information in the input (such as parentheses, spaces, and so on) but not the meta-information about which grammatical structures it represents. The AST contains only the relevant parts of the input but includes grammatical information on top of that. If you want, you can consider first parsing and then translating the result into an AST as two separate steps in handling an input language. I consider them part of the same and will claim that a parser constructs an AST.

  3. 3.

    Notice, however, that there is a distinction between giving a statement meaning and giving it the correct meaning. Just because your program computes something doesn’t mean it computes what you intended it to compute. When we construct a language, domain-specific or general, we can give meaning to statements, but we cannot—this is theoretically impossible—guarantee that it is the intended meaning. That will always be the responsibility of the programmer.

  4. 4.

    Operator precedence is a term we use to describe how “tightly” different operators bind, i.e., which operators are invoked before others, or put in another way, where we implicitly set parentheses in an expression. Multiplication binds tighter than addition—has a higher precedence—so the expression 2*x + 4*y is interpreted as (2*x) + (4*y) rather than, for example, 2*(x + (4*y)). Precedence also tells us whether operators are evaluated left to right or right to left, so x + y + z is evaluated as (x + y) + z rather than x + (y + z) because + evaluates left to right. For addition, the left-to-right or right-to-left order doesn’t matter because we will end up with the same result, but for some operators it does, for example, exponentiation, which is evaluated left to right. So, x**y**z is x**(y**z), which (usually) is different from (x**y)**z. If you use operators in a domain-specific language, the precedence of the operators will affect your language.

  5. 5.

    We haven’t formally defined how we would specify non-literate tokens in the syntax we use for specifying grammars, and doing so will not make the example any clearer, so let’s just state that informally.

  6. 6.

    If you are not familiar with continuous time Markov chains an informal description could be this: A CTMC is a graph where nodes represent states and edges transition between states, and each edge is annotated with the rate at which changes happen. The model is stochastic, so rates should be thought of as expectations of change over time. If we have a rate of 1 between states s and t, then for each time unit, we would expect to see one change from s to t. If we want to know the probability of being in state t at some time t if we are in state s at time =0, we cannot consider the states s and t in isolation. There might be other states we can go to from s and if we go to those, it might take a longer or shorter time to reach t, or there might be states we can continue to from t so we might go through t before time t but no longer be there. We have to take all edges and all rates into account. Figuring out the probability of being at state t at time t is therefore dependent on matrix operations, in particular matrix exponentiation.

Author information

Authors and Affiliations

Authors

Rights and permissions

Reprints and permissions

Copyright information

© 2018 Thomas Mailund

About this chapter

Check for updates. Verify currency and authenticity via CrossMark

Cite this chapter

Mailund, T. (2018). Components of a Programming Language. In: Domain-Specific Languages in R. Apress, Berkeley, CA. https://doi.org/10.1007/978-1-4842-3588-1_3

Download citation

Publish with us

Policies and ethics