Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions samples/CalcExpr/ExpressionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ private static Parser<double> CreateExpressionParser()
).Do((u, _, d) => u.HasValue ? -d : d);

var mul_expr =
unary_expr.Fold(
unary_expr.FoldL(
OneOf("*/").ThenIgnore(S),
(l, r, o) => o == '*' ? l * r : l / r);

sum_expr.Parser =
mul_expr.Fold(
mul_expr.FoldL(
OneOf("+-").ThenIgnore(S),
(l, r, o) => o == '+' ? l + r : l - r);

Expand Down
18 changes: 11 additions & 7 deletions samples/CalcExpr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,41 @@ This project implements a simple mathematical expression parser.

## Simple Expression Grammar

```sh
```text
start
= S sum_expr EOF
;

sum_expr
= mul_expr (S [+-] mul_expr)*
= mul_expr ([+-] S mul_expr)*
;

mul_expr
= unary_expr (S [*/] unary_expr)*
= unary_expr ([*/] S unary_expr)*
;

unary_expr
= S "-"? primary_expr
= "-"? S primary_expr
;

primary_expr
= parenthesis_expr / number_expr
;

parenthesis_expr
= S "(" Sum S ")"
= "(" S sum_expr ")" S
;

number_expr
= S [0-9]+
= number S
;

number
= [+-]? [0-9]+ ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
;

S
= [ \t\r\n]*
= [\s]*
;

EOF
Expand Down
2 changes: 1 addition & 1 deletion samples/Json/JsonParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,6 @@ public static class JsonParser
@object
).ThenIgnore(S);

return S.Then(value);
return value.Between(S, Eof);
}
}
10 changes: 4 additions & 6 deletions samples/Json/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@

This project implements a simple JSON parser.

## JSON Grammar

```sh
```text
start
= value $
= S value $
;

value
Expand All @@ -18,14 +16,14 @@ object
;

member
= string ":" S value
= string S ":" S value
;

array
= "[" S (value ("," S value)*)? "]" S
;

S
= [ \t\r\n]*
= [\s]*
;
```
16 changes: 11 additions & 5 deletions samples/TinyC/Node.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public abstract record Node
public static Node Unary(char op, Node operand) => new UnaryNode(op, operand);
public static Node Binary(string op, Node left, Node right) => new BinaryNode(op, left, right);
public static Node Assign(Node variable, Node value) => Binary("=", variable, value);
public static Node ExpressionStatement(Node expression) => new ExpressionStatementNode(expression);
public static Node Block(IReadOnlyList<Node> statements) => new BlockNode(statements);
public static Node Block(Node statement) => statement is BlockNode ? statement : new BlockNode([statement]);

Expand Down Expand Up @@ -57,6 +58,7 @@ static void Print(Node node, IndentedStringBuilder sb)
break;

case TernaryNode c:
sb.Append('(');
Print(c.Test, sb);
sb.IncrementIndent();
sb
Expand All @@ -68,6 +70,7 @@ static void Print(Node node, IndentedStringBuilder sb)
.AppendLine()
.Append(": ");
Print(c.IfFalse, sb);
sb.Append(')');
sb.DecrementIndent();
break;

Expand Down Expand Up @@ -95,8 +98,9 @@ static void Print(Node node, IndentedStringBuilder sb)
break;

case BinaryNode(Operator: "=", var variable, var expr):
sb.Append('(');
Print(variable, sb);
sb.Append(" = (");
sb.Append(" = ");
Print(expr, sb);
sb.Append(')');
break;
Expand All @@ -109,16 +113,17 @@ static void Print(Node node, IndentedStringBuilder sb)
sb.Append(')');
break;

case ExpressionStatementNode statement:
Print(statement.Expression, sb);
sb.AppendLine(";");
break;

case BlockNode block:
sb.AppendLine("{");
sb.IncrementIndent();

foreach (var stmt in block.Statements)
{
Print(stmt, sb);
if (stmt is NumberNode or VariableNode or UnaryNode or BinaryNode)
sb.AppendLine(";");
}

sb.DecrementIndent();
sb.AppendLine("}");
Expand All @@ -135,5 +140,6 @@ public sealed record WhileLoopNode(Node Test, Node Body) : Node;
public sealed record DoWhileLoopNode(Node Test, Node Body) : Node;
public sealed record UnaryNode(char Operator, Node Operand) : Node;
public sealed record BinaryNode(string Operator, Node Left, Node Right) : Node;
public sealed record ExpressionStatementNode(Node Expression) : Node;
public sealed record BlockNode(IReadOnlyList<Node> Statements) : Node;
}
58 changes: 45 additions & 13 deletions samples/TinyC/README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,66 @@
# Tiny-C

This project implements a parser for the [Tiny-C](http://www.iro.umontreal.ca/~felipe/IFT2030-Automne2002/Complements/tinyc.c) language, a highly simplified version of `C` designed as an educational tool for learning about compilers.

All variables are predefined, of integer type, and initialized to zero.
This project implements a parser for the [Tiny-C](http://www.iro.umontreal.ca/~felipe/IFT2030-Automne2002/Complements/tinyc.c) language,
a highly simplified version of `C` designed as an educational tool for learning about compilers.

The main differences from the original `Tiny-C` are:
- Variable names are not limited to single letters.
- Additional operators are supported.
- Line comments (`// ...`) and block comments (`/* ... */`) are supported.

## Tiny-C Grammar

```sh
```
start
= S statement EOF
;

keyword
= ("while" / "do" / "if" / "else") ![\w]
= while_keyword / do_keyword / if_keyword / else_keyword
;

identifier_part
= [a-zA-Z_0-9]
;

while_keyword
= "while" !identifier_part
;

do_keyword
= "do" !identifier_part
;

if_keyword
= "if" !identifier_part
;

else_keyword
= "else" !identifier_part
;

number
= [0-9]+
;

variable
= !keyword [a-zA-Z_][a-zA-Z0-9_]*
= !keyword [a-z] identifier_part*
;

S
= [ \t\n\r]*
= (single_comment / multiline_comment / [\s])*
;

single_comment
= "//" (!EOL .)* EOL
;

multiline_comment
= "/*" (!"*/" .)* "*/"
;

EOL
= "\r\n" / [\r\n\u0085\u2028\u2029] / EOF
;

EOF
Expand All @@ -44,11 +76,11 @@ number_expr
;

expr
= assigment_expr
= assignment_expr
/ ternary_expr
;

assigment_expr
assignment_expr
= var_expr "=" S expr
;

Expand Down Expand Up @@ -81,7 +113,7 @@ eq_expr
;

relational_expr
= shift_expr (("<" / "<=" / ">" / ">=") S shift_expr)*
= shift_expr (("<=" / "<" / ">=" / ">") S shift_expr)*
;

shift_expr
Expand Down Expand Up @@ -120,15 +152,15 @@ statement
;

if_statement
= "if" S "(" S expr ")" S statement ("else" S statement)?
= if_keyword S "(" S expr ")" S statement (else_keyword S statement)?
;

while_statement
= "while" S "(" S expr ")" S statement
= while_keyword S "(" S expr ")" S statement
;

do_while_statement
= "do" S statement "while" S "(" S expr ")" S ";" S
= do_keyword S statement while_keyword S "(" S expr ")" S ";" S
;

block_statement
Expand Down
Loading
Loading