April 8, 2019.
Boston, MA.

# Useful Links

Parsing:
https://en.wikipedia.org/wiki/Comparison_of_parser_generators
https://github.com/lark-parser/lark
https://github.com/antlr/grammars-v4
https://tomassetti.me/ebnf/
https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form
https://lukaszwrobel.pl/blog/math-parser-part-2-grammar/
https://lark-parser.readthedocs.io/en/latest/parsers/#earley
https://en.wikipedia.org/wiki/Chomsky_hierarchy
https://tomassetti.me/parsing-in-python/

OCW:
https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-035-computer-language-engineering-spring-2010/lecture-notes/
https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-035-computer-language-engineering-spring-2010/lecture-notes/MIT6_035S10_lec04.pdf

https://www3.cs.stonybrook.edu/~warren/xsbbook/node10.html

Math and accesibility:
http://emacspeak.sourceforge.net/raman/publications/thinking-of-math/thinking-of-math.pdf
http://www.utdallas.edu/~gupta/mathaccsurvey.pdf

Parsing:
https://tomassetti.me/guide-parsing-algorithms-terminology/

# Notes

(from https://tomassetti.me/parsing-in-python/)

Use EBNF to specify the language and the things required to interpret the "over" symbol correctly. Then use Lark or ANTLR to implement the parser.

Difference between abstract syntax tree (AST) and parse tree. The former groups tokens as a human would intuitively, while the latter is a formalized (and more complex) version which contains all necessary levels to express exact precedence relations.

Grammar consists of non-terminals and terminals, where the former are internal nodes in the parse tree and the latter are the leaves of the parse tree. In other words, the terminals are the basic units of the language, and the non-terminals are groupings of non-terminals and terminals. A grammar is usually created by thinking not how to recognize a sentence, but rather how to create a sentence. This is usually more intuitive, and the inversion process is what the parser generator does for you.

The grammar is defined in terms of the non-terminals and terminals, as well as production rules. Production rules tell us how non-terminals can transform into a sequence of non-terminals and terminals.

The most commonly used language for defining grammars is EBNF (Extended Backus-Naur Form). A thing to note about it is that most parser generators seem to have their own adapted version of EBNF, but the basic structure seems to be the same. In EBNF, productions are often called rules, and non-terminals are defined implicitly through the rule definitions (if I've understood this correctly).

---------ASIDE: Chomsky Hierarchy of Languages----------
(from https://en.wikipedia.org/wiki/Chomsky_hierarchy)

This is related, but will probably not be expressly applicable knowledge. It is interesting and I think it will be useful to understand the underlying concepts though.

Really, the only interesting thing here is the difference between context-free grammar and regular languages. Context-free grammars allow any rules (where we have a single non-terminal on the left-hand side). Regular languages only allow rules where the right-hand side has a single terminal followed by a single non-terminal. In other words, regular languages can be parsed and created linearly instead of recursively, and there are a lot of things they cannot describe. Regular expressions can be used to represent any regular language.

In conclusion, I will use both CFG and regular languages: the former in defining the semantical structure, and the latter in recognizing individual tokens.

----------END ASIDE----------

(following from https://tomassetti.me/guide-parsing-algorithms-terminology/)

Rule of thumb: if a language has a recursive structure, then a context-free grammar is needed, rather than just a regular language.

---------USEFUL NOTE----------
Note that the input language to our CFG will require a lexer with similar to the saytex syntax parser. Not sure if this means I will not be able to implement the lexer in Lark, or if it means that I could've easily implemented saytex syntax using Lark. Either way, not entirely ideal.but that's okay.
---------END USEFUL NOTE----------

(from https://tomassetti.me/guide-parsing-algorithms-terminology/)

"Scannerless parser is a better design for a language where a clear distinction between lexer and parser is difficult or unnecessary. An example is a parser for a markup language, where special markers are inserted in a sea of text. "

It feels like the CFG I want to create to recognize "over" is very much like a markup language, so I might want to look into this.

Note: some parser generators do not support recursive rules, and they seem much more cumbersome to work with. I probably want to find a parser generator supporting all kinds of recursive rules, since I need not worry about time complexity.

PEG vs CFG: PEG can be recognized in linear time and does not allow ambiguity. It eliminates ambiguity by requiring that all options are explicitly ordered by priority. I feel like PEG is not what I need, since I probably need ambiguity for SayTeX+.

## Addition April 25

Continuing notes from https://tomassetti.me/guide-parsing-algorithms-terminology/.

### Grammars

not much to say here

### Parsing Algorithms

Two approaches: top-down and bottom-up. The first one tries to first identify the root and then recurse, while the second one tries to identify a leaf element and build from there (possibly in a linear fashion?). Left-most versus right-most derivation is related to top-down versus bottom-up in some way, but it is unclear how. Top-down uses DFS.

Chart parsers uses dynamic programming (makes sense). To learn more about parsing algorithms, the following paper presenting the Earley algorithm seems like a good resource: http://staff.icar.cnr.it/ruffolo/progetti/projects/10.Parsing%20Earley/1970-An%20efficient%20context-free%20parsing%20algorithm-earley.pdf. 

