From 97959a65e65d7e78e548ab1652f2f84423f55b6e Mon Sep 17 00:00:00 2001 From: Korunka1 Date: Tue, 5 Dec 2023 19:19:21 +0100 Subject: [PATCH 1/4] documenation of expression parser + precedence table --- docs/doc.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/doc.md b/docs/doc.md index d1e78b8..192fa95 100644 --- a/docs/doc.md +++ b/docs/doc.md @@ -203,6 +203,12 @@ Pokud parser úspěšně zpracuje všechny vytvořené tokeny, vrátí syntaktic #### Precedenční analýza +Precedenční analýza výrazů je implementována v souboru `ExpressionParser.c`. Analýza probíhá na základě precedenční tabulky. Pro precedenční analýzu jsou použity dva zásobníky - hlavní a pomocný, oba implementované jako dynamické pole v souboru `Array.c`. Hlavní zásobník slouží k uchování tokenů a mezivýsledků během analýzy a je z něj odebrán konečný výsledek analýzy, který je pomocí makra `ParserSucces` společně s řízením předán zpět rekurzivní analýze. Pomocný zásobník je využíván pro redukce pravidel, při kterých se vytváří jednotlivé větve AST. V případě neúspěšné redukce vrací precedenční analýza rekurzivní analýze `ParserError`. Zásobníky obsahují strukturu `StackItem`, která v sobě uchovává ukazatel na token, ukazatel na větev AST, informaci o tom, zda je token terminál nebo neterminál a v důsledku rozšíření BOOLTHEN obsahuje také informaci o tom, jestli je operátor postfixový nebo prefixový. + +Obslužná rutina v případě, kdy precedenční tabulka vrátí symbol X (značící chybu), spočívá ve snaze o úspěšné zpracování (redukci) současného obsahu hlavního zásobníku. Pokud je pokus neúspěšný, vrátí precedenční analýza chybový kód a hlášku, v opačném případě se výraz úspěšně vyhodnotí. + +Do precedenční analýzy bylo přidáno několik rozšíření. BOOLTHEN je implementováno přidáním operátorů do precedenční tabulky. FUNEXP a INTERPOLATION jsou řešena pomocí kontroly současně zpracovávaného a nadcházejícího tokenu. Pokud je vyhodnoceno, že se jedná o funkci nebo string interpolation, je zavolána funkce `__Parser_parseFunctionCallExpression` resp. `__Parser_parseStringInterpolation`, po zpracování části výrazu pomocnými funkcemi analýza dále pokračuje. + ### Sémantická analýza // TODO: symtable.c @@ -284,6 +290,29 @@ Projekt ďalej obsahuje súčasti ako `colors.h`, ktorá definuje základné ASC
+### Precedenční tabulka +| | + - | * / | x! | ?? | r | i | ( | ) | !x | \|\| | && | $ | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---- | --- | --- | +| __+ -__ | R | S |S | R | R | S | S | R | S | R | R | R | +|__* /__ | R | R |S | R | R | S | S | R | S | R | R | R | +| __x!__ | R | R |X | R | R | X | X | R | R | R | R | R | +| __??__ | S | S |S | S | S | S | S | R | S | S | S | R | +| __r__ | S | S |S | R | X | S | S | R | S | R | R | R | +| __i__ | R | R |R | R | R | X | X | R | X | R | R | R | +| __(__ | S | S |S | S | S | S | S | E | S | S | S | X | +| __)__ | R | R |R | R | R | X | X | R | X | R | R | R | +| __!x__ | R | R |S | R | R | S | S | R | X | R | R | R | +| __\|\|__ | S | S |S | S | S | S | S | R | S | R | R | R | +| __&&__ | S | S |S | S | S | S | S | R | S | R | R | R | +| __$__ | S | S |S | S | S | S | S | X | S | S | S | X | + +Pozn.: +- r: relační operátory ==, !=, <, >, <=, >= +- i: literály +- R: > +- S: < +- E: = +- X: Invalid --- From f824e3a2ea029bf28187211d28a9133b4c229c80 Mon Sep 17 00:00:00 2001 From: Radim Mifka Date: Wed, 6 Dec 2023 01:42:00 +0100 Subject: [PATCH 2/4] Change grammar to proper ll-grammar --- docs/ll_grammar.md | 72 ++++++++++++++++++++++++++++++++++ src/compiler/parser/grammar.md | 31 ++++++++++++--- 2 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 docs/ll_grammar.md diff --git a/docs/ll_grammar.md b/docs/ll_grammar.md new file mode 100644 index 0000000..df33143 --- /dev/null +++ b/docs/ll_grammar.md @@ -0,0 +1,72 @@ +## LL-Gramatika +1. program → statements +2. program → ε +3. code-block → `{` statements `}` +4. statements → statement statements +5. statements → ε +8. statement → function-declaration +9. statement → variable-declaration +10. statement → if-statement +11. statement → while-statement +12. statement → for-in-statement +13. statement → continue-statement +14. statement → break-statement +15. statement → return-statement +16. statement → expression-statement +17. expression-statement → expression +18. function-declaration → `func` function-name function-signature function-body +19. function-name → identifier +20. function-signature → parameter-clause function-result +21. function-result → `->` type +22. function-result → ε +23. function-body → code-block +24. function-body → ε +25. parameter-clause → `(` parameter-list `)` +26. parameter-list → parameter +27. parameter-list → parameter `,` parameter-list +28. parameter-list → ε +29. parameter → external-parameter-name local-parameter-name type-annotation initializer +30. external-parameter-name → identifier +31. local-parameter-name → identifier +32. initializer → `=` expression +33. initializer → ε +34. function-call-expression → function-name argument-clause +35. argument-clause → `(` argument-list `)` +36. argument-list → argument +37. argument-list → argument `,` argument-list +38. argument-list → ε +39. argument → argument-name `:` expression +40. argument → expression +41. argument-name → identifier +42. assignment-statement → variable-name assignment-expression +43. assignment-expression → `=` expression +44. variable-declaration → variable-head variable-declaration-list +45. variable-head → `let` +46. variable-head → `var` +47. variable-name → identifier +48. variable-declaration-list → variable-declarator +49. variable-declaration-list → variable-declarator `,` variable-declaration-list +50. variable-declaration-list → ε +51. variable-declarator → pattern initializer +52. pattern → variable-name type-annotation +53. type-annotation → `:` type +54. type-annotation → ε +55. type → identifier +56. if-statement → `if` condition code-block else-clause +57. else-clause → `else` code-block +58. else-clause → `else` if-statement +59. else-clause → ε +60. condition → expression +61. condition → optional-binding-condition +62. optional-binding-condition → `let` pattern initializer +63. optional-binding-condition → `var` pattern initializer +64. while-statement → `while` condition code-block +65. for-in-statement → `for` variable-name `in` range code-block +66. range → close-range +67. range → half-open-range +68. close-range → expression...expression +69. half-open-range → expression.. -//type → `String` | `Int` | `Double`
-type → identifier // Built-in types will be resolved at semantic analysis
- +program → statements? code-block → `{` statements? `}`
+statements → statement statements + +type-annotation → `:` type
+type → identifier + ## literals literal → numeric-literal | string-literal | boolean-literal | nil-literal
@@ -59,6 +61,9 @@ statement → function-declaration
statement → variable-declaration
statement → if-statement
statement → while-statement
+statement → for-in-statement
+statement → continue-statement
+statement → break-statement
statement → return-statement
statement → expression-statement
@@ -76,7 +81,7 @@ function-body → code-block
parameter-clause → `(` `)` | `(` parameter-list `)`
parameter-list → parameter | parameter `,` parameter-list
-parameter → external-parameter-name? local-parameter-name type-annotation initializer?
+parameter → external-parameter-name local-parameter-name type-annotation initializer?
external-parameter-name → identifier
local-parameter-name → identifier
@@ -120,6 +125,22 @@ else-clause → `else` code-block | `else` if-statement
while-statement → `while` condition code-block
+## for in statement + +for-in-statement → `for` variable-name `in` range code-block
+ +range → close-range | half-open-range
+close-range → expression...expression
+half-open-range → expression.. + +## continue statement + +continue-statement → `continue`
+ +## break statement + +break-statement → `break`
+ ## return statement return-statement → `return` expression?
From 1731bbc208de673385b88d2cd7511b43e4e23c6e Mon Sep 17 00:00:00 2001 From: Radim Mifka Date: Wed, 6 Dec 2023 01:54:17 +0100 Subject: [PATCH 3/4] Add function-call-expression to ll-grammar --- docs/ll_grammar.md | 133 +++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 66 deletions(-) diff --git a/docs/ll_grammar.md b/docs/ll_grammar.md index df33143..7bbe882 100644 --- a/docs/ll_grammar.md +++ b/docs/ll_grammar.md @@ -4,69 +4,70 @@ 3. code-block → `{` statements `}` 4. statements → statement statements 5. statements → ε -8. statement → function-declaration -9. statement → variable-declaration -10. statement → if-statement -11. statement → while-statement -12. statement → for-in-statement -13. statement → continue-statement -14. statement → break-statement -15. statement → return-statement -16. statement → expression-statement -17. expression-statement → expression -18. function-declaration → `func` function-name function-signature function-body -19. function-name → identifier -20. function-signature → parameter-clause function-result -21. function-result → `->` type -22. function-result → ε -23. function-body → code-block -24. function-body → ε -25. parameter-clause → `(` parameter-list `)` -26. parameter-list → parameter -27. parameter-list → parameter `,` parameter-list -28. parameter-list → ε -29. parameter → external-parameter-name local-parameter-name type-annotation initializer -30. external-parameter-name → identifier -31. local-parameter-name → identifier -32. initializer → `=` expression -33. initializer → ε -34. function-call-expression → function-name argument-clause -35. argument-clause → `(` argument-list `)` -36. argument-list → argument -37. argument-list → argument `,` argument-list -38. argument-list → ε -39. argument → argument-name `:` expression -40. argument → expression -41. argument-name → identifier -42. assignment-statement → variable-name assignment-expression -43. assignment-expression → `=` expression -44. variable-declaration → variable-head variable-declaration-list -45. variable-head → `let` -46. variable-head → `var` -47. variable-name → identifier -48. variable-declaration-list → variable-declarator -49. variable-declaration-list → variable-declarator `,` variable-declaration-list -50. variable-declaration-list → ε -51. variable-declarator → pattern initializer -52. pattern → variable-name type-annotation -53. type-annotation → `:` type -54. type-annotation → ε -55. type → identifier -56. if-statement → `if` condition code-block else-clause -57. else-clause → `else` code-block -58. else-clause → `else` if-statement -59. else-clause → ε -60. condition → expression -61. condition → optional-binding-condition -62. optional-binding-condition → `let` pattern initializer -63. optional-binding-condition → `var` pattern initializer -64. while-statement → `while` condition code-block -65. for-in-statement → `for` variable-name `in` range code-block -66. range → close-range -67. range → half-open-range -68. close-range → expression...expression -69. half-open-range → expression..` type +21. function-result → ε +22. function-body → code-block +23. function-body → ε +24. parameter-clause → `(` parameter-list `)` +25. parameter-list → parameter +26. parameter-list → parameter `,` parameter-list +27. parameter-list → ε +28. parameter → external-parameter-name local-parameter-name type-annotation initializer +29. external-parameter-name → identifier +30. local-parameter-name → identifier +31. initializer → `=` expression +32. initializer → ε +33. function-call-expression → function-name argument-clause +34. argument-clause → `(` argument-list `)` +35. argument-list → argument +36. argument-list → argument `,` argument-list +37. argument-list → ε +38. argument → argument-name `:` expression +39. argument → expression +40. argument-name → identifier +41. assignment-statement → variable-name assignment-expression +42. assignment-expression → `=` expression +43. variable-declaration → variable-head variable-declaration-list +44. variable-head → `let` +45. variable-head → `var` +46. variable-name → identifier +47. variable-declaration-list → variable-declarator +48. variable-declaration-list → variable-declarator `,` variable-declaration-list +49. variable-declaration-list → ε +50. variable-declarator → pattern initializer +51. pattern → variable-name type-annotation +52. type-annotation → `:` type +53. type-annotation → ε +54. type → identifier +55. if-statement → `if` condition code-block else-clause +56. else-clause → `else` code-block +57. else-clause → `else` if-statement +58. else-clause → ε +59. condition → expression +60. condition → optional-binding-condition +61. optional-binding-condition → `let` pattern initializer +62. optional-binding-condition → `var` pattern initializer +63. while-statement → `while` condition code-block +64. for-in-statement → `for` variable-name `in` range code-block +65. range → close-range +66. range → half-open-range +67. close-range → expression...expression +68. half-open-range → expression.. Date: Wed, 6 Dec 2023 11:35:16 +0100 Subject: [PATCH 4/4] Remove unnecessary rules --- docs/ll_grammar.md | 114 ++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 59 deletions(-) diff --git a/docs/ll_grammar.md b/docs/ll_grammar.md index 7bbe882..ba12aa8 100644 --- a/docs/ll_grammar.md +++ b/docs/ll_grammar.md @@ -1,4 +1,5 @@ ## LL-Gramatika + 1. program → statements 2. program → ε 3. code-block → `{` statements `}` @@ -12,62 +13,57 @@ 11. statement → continue-statement 12. statement → break-statement 13. statement → return-statement -14. statement → function-call-expression -15. statement → expression-statement -16. expression-statement → expression -17. function-declaration → `func` function-name function-signature function-body -18. function-name → identifier -19. function-signature → parameter-clause function-result -20. function-result → `->` type -21. function-result → ε -22. function-body → code-block -23. function-body → ε -24. parameter-clause → `(` parameter-list `)` -25. parameter-list → parameter -26. parameter-list → parameter `,` parameter-list -27. parameter-list → ε -28. parameter → external-parameter-name local-parameter-name type-annotation initializer -29. external-parameter-name → identifier -30. local-parameter-name → identifier -31. initializer → `=` expression -32. initializer → ε -33. function-call-expression → function-name argument-clause -34. argument-clause → `(` argument-list `)` -35. argument-list → argument -36. argument-list → argument `,` argument-list -37. argument-list → ε -38. argument → argument-name `:` expression -39. argument → expression -40. argument-name → identifier -41. assignment-statement → variable-name assignment-expression -42. assignment-expression → `=` expression -43. variable-declaration → variable-head variable-declaration-list -44. variable-head → `let` -45. variable-head → `var` -46. variable-name → identifier -47. variable-declaration-list → variable-declarator -48. variable-declaration-list → variable-declarator `,` variable-declaration-list -49. variable-declaration-list → ε -50. variable-declarator → pattern initializer -51. pattern → variable-name type-annotation -52. type-annotation → `:` type -53. type-annotation → ε -54. type → identifier -55. if-statement → `if` condition code-block else-clause -56. else-clause → `else` code-block -57. else-clause → `else` if-statement -58. else-clause → ε -59. condition → expression -60. condition → optional-binding-condition -61. optional-binding-condition → `let` pattern initializer -62. optional-binding-condition → `var` pattern initializer -63. while-statement → `while` condition code-block -64. for-in-statement → `for` variable-name `in` range code-block -65. range → close-range -66. range → half-open-range -67. close-range → expression...expression -68. half-open-range → expression..` type +20. function-result → ε +21. function-body → code-block +22. function-body → ε +23. parameter-clause → `(` parameter-list `)` +24. parameter-list → parameter +25. parameter-list → parameter `,` parameter-list +26. parameter-list → ε +27. parameter → external-parameter-name local-parameter-name type-annotation +28. external-parameter-name → identifier +29. local-parameter-name → identifier +30. function-call-expression → function-name argument-clause +31. argument-clause → `(` argument-list `)` +32. argument-list → argument +33. argument-list → argument `,` argument-list +34. argument-list → ε +35. argument → argument-name `:` expression +36. argument → expression +37. argument-name → identifier +38. assignment-statement → variable-name `=` expression +39. variable-declaration → variable-head variable-declaration-list +40. variable-head → `let` +41. variable-head → `var` +42. variable-name → identifier +43. variable-declaration-list → variable-declarator +44. variable-declaration-list → variable-declarator `,` variable-declaration-list +45. variable-declaration-list → ε +46. variable-declarator → pattern `=` expression +47. variable-declarator → pattern +48. pattern → variable-name type-annotation +49. type-annotation → `:` type +50. type-annotation → ε +51. type → identifier +52. if-statement → `if` condition code-block else-clause +53. else-clause → `else` code-block +54. else-clause → `else` if-statement +55. else-clause → ε +56. condition → expression +57. condition → optional-binding-condition +58. optional-binding-condition → variable-head variable-declarator +59. while-statement → `while` condition code-block +60. for-in-statement → `for` variable-name `in` range code-block +61. range → expression range-operator expression +62. range-operator → `...` +63. range-operator → `..<` +64. continue-statement → `continue` +65. break-statement → `break` +66. return-statement → `return` expression +67. return-statement → `return`