Entry tags:
Ungrammar
Почему бы не подурачиться 1 апреля. Думаю, парсер грамматики Си вполне сойдёт за дурацкую затею. Тем более я ж не сам напрягаться собираюсь, а ИИ подряжу. Я упоминал про ASDL, а есть ещё Ungrammar, другой способ описывать синтаксические деревья. Я попросил Грок сбацать мне грамматику языка Си. Он предложил упрощённый вариант:
В качестве теста обработаем Си-шную программу:
Неплохо, вполне годится. А теперь говорю, напиши парсер этой грамматики на Rust. С третьей попытки получился работающий код: c_parser/src/main.rs. Полтыщи строк нетривиального кода одним махом побиваши.// Top-level program structure
TranslationUnit = Declaration*
// Declarations
Declaration = Type Identifier ';'
| Type Identifier '(' ParameterList ')' CompoundStmt
ParameterList = (Type Identifier (',' Type Identifier)*)?
// Types
Type = 'int'
| 'float'
| 'char'
| 'void'
// Statements
Stmt = CompoundStmt
| ExprStmt
| IfStmt
| WhileStmt
| ReturnStmt
CompoundStmt = '{' Declaration* Stmt* '}'
ExprStmt = Expr ';'
IfStmt = 'if' '(' Expr ')' Stmt ('else' Stmt)?
WhileStmt = 'while' '(' Expr ')' Stmt
ReturnStmt = 'return' Expr? ';'
// Expressions
Expr = AssignmentExpr
AssignmentExpr = EqualityExpr ('=' EqualityExpr)?
EqualityExpr = RelationalExpr (('==' | '!=') RelationalExpr)?
RelationalExpr = AddExpr (('<' | '>' | '<=' | '>=') AddExpr)?
AddExpr = MultExpr (('+' | '-') MultExpr)*
MultExpr = UnaryExpr (('*' | '/') UnaryExpr)*
UnaryExpr = PrimaryExpr
| '-' UnaryExpr
| '!' UnaryExpr
PrimaryExpr = Identifier
| Number
| String
| '(' Expr ')'
// Basic tokens
Identifier = <token>
Number = <token>
String = <token>
В качестве теста обработаем Си-шную программу:
Компилируем, запускаем:int x = 42;
int main(int argc) {
int y = 3 + 5 * 2;
if (y > x) {
return 1;
} else {
return 0;
}
}
Остаётся добавить указатели, массивы, структуры, тайпдефы и прочие фичи, и язык Си у нас в кармане. 😀$ cargo run ...
Running `/home/vak/c_parser/target/debug/c_parser`
TranslationUnit {
declarations: [
Variable(
Int,
"x",
Some(
Number(
42,
),
),
),
Function(
Int,
"main",
[
Parameter(
Int,
"argc",
),
],
CompoundStmt {
declarations: [
Variable(
Int,
"y",
Some(
Binary(
Number(
3,
),
Add,
Binary(
Number(
5,
),
Mul,
Number(
2,
),
),
),
),
),
],
statements: [
If(
Binary(
Identifier(
"y",
),
Greater,
Identifier(
"x",
),
),
Compound(
CompoundStmt {
declarations: [],
statements: [
Return(
Some(
Number(
1,
),
),
),
],
},
),
Some(
Compound(
CompoundStmt {
declarations: [],
statements: [
Return(
Some(
Number(
0,
),
),
),
],
},
),
),
),
],
},
),
],
}
no subject
no subject
https://github.com/sergev/vak-opensource/blob/master/languages/pascal/cparser.pas
Весь мой диалог с ним здесь: https://grok.com/share/bGVnYWN5_865d8aec-3931-4cd6-9fe4-8f5c9870432d
no subject
no subject
no subject
no subject
no subject
no subject