summaryrefslogtreecommitdiff
path: root/chapter17b
diff options
context:
space:
mode:
Diffstat (limited to 'chapter17b')
-rw-r--r--chapter17b/README.ja.md4
-rw-r--r--chapter17b/README.md3
-rw-r--r--chapter17b/docs/17-grammar.ja.md132
-rw-r--r--chapter17b/docs/17-grammar.md139
4 files changed, 240 insertions, 38 deletions
diff --git a/chapter17b/README.ja.md b/chapter17b/README.ja.md
index 68f5c389..94585031 100644
--- a/chapter17b/README.ja.md
+++ b/chapter17b/README.ja.md
@@ -7,6 +7,8 @@
この文書は [原文](README.md) の日本語訳です。
+この章の[完全な言語文法](docs/17-grammar.ja.md)はこちらです。
+
## 目次
1. [前置・後置インクリメント](#前置後置インクリメント)
@@ -15,8 +17,6 @@
4. [三項演算](#三項演算)
5. [for ループ](#for-ループ)
-> 訳注: 原文の目次にある「Memory effects」に対応する節は、原文本文にはありません。
-
第17a章では、代入で確認する権限を確立しました。この章ではその権限を変えずに、代入と制御フローを短く書く方法を追加します。その後、第18章で関数と呼び出しを導入します。
## 前置・後置インクリメント
diff --git a/chapter17b/README.md b/chapter17b/README.md
index 1b3a41af..d2c73584 100644
--- a/chapter17b/README.md
+++ b/chapter17b/README.md
@@ -6,6 +6,8 @@ English | [日本語](README.ja.md)
[Next: Chapter 18](../chapter18/README.md)
+Here is the [complete language grammar](docs/17-grammar.md) for this chapter.
+
## Table of Contents
1. [Pre/Post-increment](#prepost-increment)
@@ -13,7 +15,6 @@ English | [日本語](README.ja.md)
3. [var/val](#var--val)
4. [Trinary](#trinary)
5. [For Loops](#for-loops)
-6. [Memory effects](#memory-effects)
Chapter 17a established the permissions checked by assignments. This chapter
adds shorter ways to write assignments and control flow without changing those
diff --git a/chapter17b/docs/17-grammar.ja.md b/chapter17b/docs/17-grammar.ja.md
index c90a9d5b..284a3de3 100644
--- a/chapter17b/docs/17-grammar.ja.md
+++ b/chapter17b/docs/17-grammar.ja.md
@@ -1,21 +1,123 @@
-# 第17b章の文法の追加
+# 第17b章の文法
[English](17-grammar.md) | 日本語
-この文書は [原文](17-grammar.md) の日本語訳です。
+```antlrv4
+grammar SimpleLanguage;
-[第17a章の宣言構文](../../chapter17a/docs/17-grammar.ja.md)から始めます。この章は、型推論、代入の短縮形、条件式、`for` ループを追加します。アクセスと束縛の権限の意味は変わりません。
+// Name lookup, assignable operands, type compatibility, and access permissions
+// are checked by the compiler in addition to these syntax rules.
+program : statement* EOF ;
-```text
-inferredDeclaration = ("var" | "val") ("!" | "~")? identifier "=" assignment
-assignment = expression (assignmentOperator assignment)?
-assignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "&=" | "|=" | "^="
- | "<<=" | ">>=" | ">>>="
-expression = bitwise ("?" assignment (":" assignment)?)?
-prefixUpdate = ("++" | "--") identifier
-postfixUpdate = lvalue ("++" | "--")
-forStatement = "for" "(" declarationOrExpression? ";" assignment? ";"
- assignment? ")" statement
-```
+block : '{' statement* '}' ;
+
+statement
+ : block
+ | returnStatement
+ | ifStatement
+ | whileStatement
+ | forStatement
+ | breakStatement
+ | continueStatement
+ | structDeclaration
+ | declaration ';'
+ | assignment ';'
+ | ';'
+ ;
+
+returnStatement : 'return' assignment ';' ;
+ifStatement : 'if' '(' assignment ')' statement ('else' statement)? ;
+whileStatement : 'while' '(' assignment ')' statement ;
+breakStatement : 'break' ';' ;
+continueStatement : 'continue' ';' ;
+
+forStatement
+ : 'for' '(' (declaration | assignment)? ';' assignment? ';' assignment? ')' statement
+ ;
+
+structDeclaration : 'struct' IDENTIFIER block ';' ;
+
+declaration : declarationType binding (',' binding)* ;
+declarationType : type | 'var' | 'val' ;
+binding : bindingModifier? IDENTIFIER ('=' initializer)? ;
+bindingModifier : '!' | '~' ;
+initializer : assignment ;
+
+// The prefix qualifies the named struct reference, not an enclosing array.
+// Each [] / [~] suffix qualifies its own array layer. ? requires a reference.
+type
+ : primitiveType typeSuffix*
+ | accessModifier? typeName typeSuffix*
+ ;
+accessModifier : '!' | '~' ;
+typeSuffix : '?' | '[]' | '[~]' ;
+typeName : IDENTIFIER ;
+
+primitiveType
+ : 'int' | 'i8' | 'i16' | 'i32' | 'i64'
+ | 'u1' | 'u8' | 'u16' | 'u32' | 'byte' | 'bool'
+ | 'flt' | 'f32' | 'f64'
+ ;
+
+assignment : expression (assignmentOperator assignment)? ;
+assignmentOperator
+ : '=' | '+=' | '-=' | '*=' | '/=' | '&=' | '|=' | '^='
+ | '<<=' | '>>=' | '>>>='
+ ;
+
+expression : bitwiseExpression ('?' assignment (':' assignment)?)? ;
-宣言には、コンマで区切った複数の名前を含められます。`var` は再代入を許し、`val` は束縛を固定します。両方とも初期化子の参照の権限を維持します。後置の更新はフィールドと配列要素もサポートします。前置の更新は、今のところ局所名をサポートします。評価順序については [README](../README.ja.md) を参照してください。
+bitwiseExpression
+ : comparisonExpression (('&' | '|' | '^') comparisonExpression)*
+ ;
+
+comparisonExpression
+ : shiftExpression (('==' | '!=' | '<' | '<=' | '>' | '>=') shiftExpression)*
+ ;
+
+shiftExpression
+ : additiveExpression (('<<' | '>>' | '>>>') additiveExpression)*
+ ;
+
+additiveExpression
+ : multiplicativeExpression (('+' | '-') multiplicativeExpression)*
+ ;
+
+multiplicativeExpression
+ : unaryExpression (('*' | '/') unaryExpression)*
+ ;
+
+unaryExpression
+ : ('-' | '!') unaryExpression
+ | updateOperator IDENTIFIER
+ | postfixExpression
+ ;
+
+// Prefix updates require a local name; postfix updates also allow fields
+// and array elements. All updates require an assignable operand.
+updateOperator : '++' | '--' ;
+postfixExpression : primaryExpression postfixSuffix* updateOperator? ;
+postfixSuffix : '.' IDENTIFIER | '[' assignment ']' | '#' ;
+
+primaryExpression
+ : INTEGER_LITERAL
+ | FLOAT_LITERAL
+ | 'true'
+ | 'false'
+ | 'null'
+ | IDENTIFIER
+ | '(' assignment ')'
+ | newExpression
+ ;
+
+// Struct initialization uses a block; array allocation supplies a length.
+newExpression : 'new' type ('[' assignment ']' | block)? ;
+
+INTEGER_LITERAL : '0' | [1-9] DIGIT* ;
+FLOAT_LITERAL : DIGIT+ ('.' DIGIT* ('e' DIGIT+)? | 'e' DIGIT+) ;
+IDENTIFIER : NON_DIGIT (NON_DIGIT | DIGIT)* ;
+fragment NON_DIGIT : [a-zA-Z_] ;
+fragment DIGIT : [0-9] ;
+WHITESPACE : [ \t\r\n]+ -> skip ;
+LINE_COMMENT : '//' ~[\r\n]* -> skip ;
+```
diff --git a/chapter17b/docs/17-grammar.md b/chapter17b/docs/17-grammar.md
index d42fcba1..88f6fc93 100644
--- a/chapter17b/docs/17-grammar.md
+++ b/chapter17b/docs/17-grammar.md
@@ -1,24 +1,123 @@
-# Chapter 17b grammar additions
+# Grammar for Chapter 17b
English | [日本語](17-grammar.ja.md)
-Start with [Chapter 17a's declaration syntax](../../chapter17a/docs/17-grammar.md).
-This chapter adds inference, assignment shortcuts, conditional expressions, and
-`for` loops. Access and binding permissions keep the same meaning.
-
-```text
-inferredDeclaration = ("var" | "val") ("!" | "~")? identifier "=" assignment
-assignment = expression (assignmentOperator assignment)?
-assignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "&=" | "|=" | "^="
- | "<<=" | ">>=" | ">>>="
-expression = bitwise ("?" assignment (":" assignment)?)?
-prefixUpdate = ("++" | "--") identifier
-postfixUpdate = lvalue ("++" | "--")
-forStatement = "for" "(" declarationOrExpression? ";" assignment? ";"
- assignment? ")" statement
-```
+```antlrv4
+grammar SimpleLanguage;
+
+// Name lookup, assignable operands, type compatibility, and access permissions
+// are checked by the compiler in addition to these syntax rules.
+program : statement* EOF ;
+
+block : '{' statement* '}' ;
+
+statement
+ : block
+ | returnStatement
+ | ifStatement
+ | whileStatement
+ | forStatement
+ | breakStatement
+ | continueStatement
+ | structDeclaration
+ | declaration ';'
+ | assignment ';'
+ | ';'
+ ;
+
+returnStatement : 'return' assignment ';' ;
+ifStatement : 'if' '(' assignment ')' statement ('else' statement)? ;
+whileStatement : 'while' '(' assignment ')' statement ;
+breakStatement : 'break' ';' ;
+continueStatement : 'continue' ';' ;
+
+forStatement
+ : 'for' '(' (declaration | assignment)? ';' assignment? ';' assignment? ')' statement
+ ;
+
+structDeclaration : 'struct' IDENTIFIER block ';' ;
+
+declaration : declarationType binding (',' binding)* ;
+declarationType : type | 'var' | 'val' ;
+binding : bindingModifier? IDENTIFIER ('=' initializer)? ;
+bindingModifier : '!' | '~' ;
+initializer : assignment ;
+
+// The prefix qualifies the named struct reference, not an enclosing array.
+// Each [] / [~] suffix qualifies its own array layer. ? requires a reference.
+type
+ : primitiveType typeSuffix*
+ | accessModifier? typeName typeSuffix*
+ ;
+accessModifier : '!' | '~' ;
+typeSuffix : '?' | '[]' | '[~]' ;
+typeName : IDENTIFIER ;
+
+primitiveType
+ : 'int' | 'i8' | 'i16' | 'i32' | 'i64'
+ | 'u1' | 'u8' | 'u16' | 'u32' | 'byte' | 'bool'
+ | 'flt' | 'f32' | 'f64'
+ ;
+
+assignment : expression (assignmentOperator assignment)? ;
+assignmentOperator
+ : '=' | '+=' | '-=' | '*=' | '/=' | '&=' | '|=' | '^='
+ | '<<=' | '>>=' | '>>>='
+ ;
-Declarations can contain several comma-separated names. `var` permits
-reassignment and `val` fixes the binding; both retain the initializer's reference
-permissions. Postfix updates also support fields and array elements. Prefix
-updates currently support local names. See the README for evaluation order.
+expression : bitwiseExpression ('?' assignment (':' assignment)?)? ;
+
+bitwiseExpression
+ : comparisonExpression (('&' | '|' | '^') comparisonExpression)*
+ ;
+
+comparisonExpression
+ : shiftExpression (('==' | '!=' | '<' | '<=' | '>' | '>=') shiftExpression)*
+ ;
+
+shiftExpression
+ : additiveExpression (('<<' | '>>' | '>>>') additiveExpression)*
+ ;
+
+additiveExpression
+ : multiplicativeExpression (('+' | '-') multiplicativeExpression)*
+ ;
+
+multiplicativeExpression
+ : unaryExpression (('*' | '/') unaryExpression)*
+ ;
+
+unaryExpression
+ : ('-' | '!') unaryExpression
+ | updateOperator IDENTIFIER
+ | postfixExpression
+ ;
+
+// Prefix updates require a local name; postfix updates also allow fields
+// and array elements. All updates require an assignable operand.
+updateOperator : '++' | '--' ;
+postfixExpression : primaryExpression postfixSuffix* updateOperator? ;
+postfixSuffix : '.' IDENTIFIER | '[' assignment ']' | '#' ;
+
+primaryExpression
+ : INTEGER_LITERAL
+ | FLOAT_LITERAL
+ | 'true'
+ | 'false'
+ | 'null'
+ | IDENTIFIER
+ | '(' assignment ')'
+ | newExpression
+ ;
+
+// Struct initialization uses a block; array allocation supplies a length.
+newExpression : 'new' type ('[' assignment ']' | block)? ;
+
+INTEGER_LITERAL : '0' | [1-9] DIGIT* ;
+FLOAT_LITERAL : DIGIT+ ('.' DIGIT* ('e' DIGIT+)? | 'e' DIGIT+) ;
+IDENTIFIER : NON_DIGIT (NON_DIGIT | DIGIT)* ;
+fragment NON_DIGIT : [a-zA-Z_] ;
+fragment DIGIT : [0-9] ;
+WHITESPACE : [ \t\r\n]+ -> skip ;
+LINE_COMMENT : '//' ~[\r\n]* -> skip ;
+```