-
Notifications
You must be signed in to change notification settings - Fork 0
Putting the process through its paces #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # Introduction | ||
|
|
||
| Programming languages are fundamental tools for software developers. Their | ||
| design shapes the way we think about problems, express solutions, and organize | ||
| programs into maintainable systems. | ||
|
|
||
| ## Why study programming languages? | ||
|
|
||
| Every programmer needs a deep understanding of programming languages to learn | ||
| them more easily, to use them more effectively, to evaluate their strengths and | ||
| weaknesses (particularly when assessing a new language), and to design new ones. | ||
|
|
||
| Most programmers think they'll never design a new programming language. However, | ||
| programming languages are one important tool of automation and abstraction. You | ||
| may never need to create a full-fledged, general-purpose language, but you may | ||
| need to design a special-purpose programming language (also called a | ||
| domain-specific language) that eases solving a narrow class of problems. | ||
|
|
||
| ## Methodology | ||
|
|
||
| To deepen our understanding of programming languages, we are going to devise | ||
| some. We will start with a very simple language, and incrementally build on that | ||
| language to study increasingly more sophisticated ones. As we do, we will | ||
| explore core concepts that appear in many modern and classic programming | ||
| languages. | ||
|
|
||
| A programming language consists of two parts: syntax and semantics. **Syntax** | ||
| describes the notation we use to write programs in a particular language. | ||
| **Semantics** defines the meaning of programs written in a language; that is, | ||
| what a program does when we run it. | ||
|
|
||
| The syntax of a language is the programmer's interface to a language. From this | ||
| perspective, syntax is important. Poor syntax makes programming an onerous task. | ||
| An better syntax can make a language less error prone, easier to type, easier | ||
| to understand, and easier to maintain. | ||
|
|
||
| Semantics is the engine of a language. It establishes the expressive power of a | ||
| language. It is where we decide if a language support iterative statements, | ||
| conditional statements, exception handling, goto statements, functions, | ||
| procedures, closures, type checking, classes and objects, out parameters, in-out | ||
| parameters, passing parameters by reference, passing parameters by value, | ||
| continuations, parallelism, side-effects, unification, etc. | ||
|
|
||
| Because semantics embodies the core of a programming language, it is where we | ||
| want to spend most our time in this course. We are going to build many, rather | ||
| ugly, languages. But these languages will support important and powerful | ||
| features! | ||
|
|
||
| To ease this process, we are going to rely on a tool: **PLCC - Programming | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want to make the distinction that we are using PLCC-ng here? Somewhere else? Or never? Personally, I think we need to make the distinction so if students start Google-ing/AI-ing (can we us AI as a verb yet?) about PLCC, they get the right variation, and can properly distinguish when they are reading docs, which they are looking at. |
||
| Languages Compiler Compiler**. It will allow us to simplify the process of | ||
| building languages by automating the generation of their parsers, allowing us to | ||
| focus our efforts on implementing their semantics. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| # Overview | ||
|
|
||
| ## Interpreter | ||
|
|
||
| A practical way to study a programming language is to build a program that can | ||
| run programs written in that language. Such a program that reads and evaluates a | ||
| program is called an **interpreter**. Most interpreters are built around three | ||
| phases: lexical analysis, syntactic analysis, and semantic analysis. | ||
|
|
||
| ```plantuml | ||
| @startuml | ||
| start | ||
| partition interpreter { | ||
| partition parser { | ||
| partition scanner { | ||
| -> string; | ||
| :lexical analysis; | ||
| -> tokens; | ||
| } | ||
| :syntactic analysis; | ||
| -> parse tree; | ||
| } | ||
| :semantic analysis; | ||
| } | ||
| -> (behavior); | ||
| stop | ||
| @enduml | ||
| ``` | ||
|
|
||
| ## PLCC | ||
|
|
||
| PLCC, first mentioned in the previous section, is a powerful tool that can | ||
| generate an interpreter. PLCC generates such an interpreter based on a textual | ||
| description of the programming language we wish to design. We refer to the | ||
| textual description as a grammar. | ||
|
|
||
| The diagram below depicts the relationships among language designers, | ||
| programmers, and PLCC. Language designers write a grammar for the language they | ||
| are designing. They use PLCC to generate an interpreter for the language from | ||
| its grammar. Then programmers write programs in this language and use the | ||
| generated interpreter to run these programs. | ||
|
|
||
| ```plantuml | ||
| @startuml | ||
| actor designer | ||
| actor programmer | ||
|
|
||
| artifact grammar [ | ||
| grammar<sub>lang</sub> | ||
| ] | ||
|
|
||
| storage plcc | ||
|
|
||
| storage interpreter [ | ||
| interpreter<sub>lang</sub> | ||
| ] | ||
|
|
||
| artifact program [ | ||
| program<sub>lang</sub> | ||
| ] | ||
|
|
||
| label behavior | ||
|
|
||
| designer .> grammar : writes | ||
| grammar -> plcc | ||
| plcc ..> interpreter :generates | ||
| program -> interpreter | ||
| interpreter -> behavior | ||
| programmer .> program : writes | ||
| @enduml | ||
| ``` | ||
|
|
||
| ## Grammar | ||
|
|
||
| In this course, you will take on the role of a language designer. As you can see | ||
| in the figure below the grammar is broken up in three parts: lexical | ||
| specification, syntactical specification, and semantic specification. The next | ||
| three sections will over each of these parts. | ||
|
|
||
| ```plantuml | ||
| @startuml | ||
| file grammar { | ||
| artifact lexspec as "lexical specification (regex)" | ||
| artifact synspec as "syntactical specification (BNF)" | ||
| artifact semspec as "semantic specification (e.g., Python)" | ||
| } | ||
|
|
||
| file source | ||
|
|
||
| node interpreter { | ||
| component parser { | ||
| component scanner { | ||
| component lexan as "lexical analysis" | ||
| } | ||
| component synan as "syntactical analysis" | ||
| } | ||
| component seman as "semantic analysis" | ||
| } | ||
|
|
||
| label behavior | ||
|
|
||
| lexspec -> lexan | ||
| synspec -> synan | ||
| semspec -> seman | ||
|
|
||
| lexspec -[hidden]-> synspec | ||
| synspec -[hidden]-> semspec | ||
|
|
||
| source --> lexan | ||
| lexan --> synan : tokens | ||
| synan --> seman : tree | ||
| seman --> behavior | ||
| @enduml | ||
| ``` | ||
|
|
||
| ## Going Beyond | ||
|
|
||
| Any program processing any input expressed in a text-based programming language | ||
| must perform lexical analysis, syntactic analysis, and semantic analysis. Such | ||
| programs include compilers, interpreters, and static analyzers (i.e., linters). | ||
| So the concepts in this section apply to all such tools. | ||
|
|
||
| We will see that the programming language specification articulated in a grammar | ||
| is itself a small programming language. We could, in principle, write a | ||
| grammar for the PLCC specification and ask PLCC to generate an alternate version | ||
| of itself. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Style guide | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good. |
||
|
|
||
| This is the style guide for the notes appearing in this folder. | ||
|
|
||
| - Use the first voice ("we"). | ||
| - Capitalize only the first word of titles | ||
| - Avoid unnecessary empty lines and trailing spaces | ||
| - Format paragraphs in 80 columns | ||
| - Let markdown applications autonumber items in ordered lists | ||
| - Use PlantUML for drawings | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we address AI here, and try to answer the question, "why should I study programming languages at all if AI is going to be the one interacting with them more than me?"
Here are some points that I think we could make:
These are not polished ideas, and you may have your own. Please feel free to shape, modify, blend, expand, contract, etc., etc., as you see fit.