From 757a725c7e4a6fe86b4b1f257202576edc88d634 Mon Sep 17 00:00:00 2001 From: Kyryl Riabov Date: Wed, 16 Oct 2024 15:34:17 +0300 Subject: [PATCH 1/3] Circom Lexer clean up --- grammar/{LexerCircom.g4 => CircomLexer.g4} | 86 ++++++++++++---------- grammar/{Circom.g4 => CircomParser.g4} | 32 ++++---- simple_listener.go | 2 +- 3 files changed, 64 insertions(+), 56 deletions(-) rename grammar/{LexerCircom.g4 => CircomLexer.g4} (53%) rename grammar/{Circom.g4 => CircomParser.g4} (82%) diff --git a/grammar/LexerCircom.g4 b/grammar/CircomLexer.g4 similarity index 53% rename from grammar/LexerCircom.g4 rename to grammar/CircomLexer.g4 index 4bfeeb4..fac543c 100644 --- a/grammar/LexerCircom.g4 +++ b/grammar/CircomLexer.g4 @@ -1,54 +1,55 @@ -lexer grammar LexerCircom; +lexer grammar CircomLexer; + +/*////////////////////////////////////////////////////////////// + COMMON STRUCTURES +//////////////////////////////////////////////////////////////*/ VERSION: NUMBER '.' NUMBER '.' NUMBER ; SIGNAL_TYPE: INPUT | OUTPUT ; -SIGNAL: 'signal' ; +/*////////////////////////////////////////////////////////////// + EXPLICIT KEYWORDS DEFINITION +//////////////////////////////////////////////////////////////*/ -INPUT: 'input' ; +PRAGMA: 'pragma' ; +CIRCOM: 'circom' ; -OUTPUT: 'output' ; +CUSTOM_TEMPLATES: 'custom_templates' ; -PUBLIC: 'public' ; +INCLUDE: 'include' ; + +CUSTOM: 'custom' ; +PARALLEL: 'parallel' ; TEMPLATE: 'template' ; +FUNCTION: 'function' ; +MAIN: 'main' ; +PUBLIC: 'public' ; COMPONENT: 'component' ; VAR: 'var' ; +SIGNAL: 'signal' ; -FUNCTION: 'function' ; - -RETURN: 'return' ; +INPUT: 'input' ; +OUTPUT: 'output' ; IF: 'if' ; - ELSE: 'else' ; FOR: 'for' ; - WHILE: 'while' ; - DO: 'do' ; LOG: 'log' ; - ASSERT: 'assert' ; -INCLUDE: 'include' ; - -CUSTOM: 'custom' ; - -PRAGMA: 'pragma' ; - -CIRCOM: 'circom' ; - -CUSTOM_TEMPLATES: 'custom_templates' ; - -MAIN: 'main' ; +RETURN: 'return' ; -PARALLEL: 'parallel' ; +/*////////////////////////////////////////////////////////////// + SYMBOLS +//////////////////////////////////////////////////////////////*/ LP: '(' ; RP: ')' ; @@ -59,31 +60,31 @@ RB: ']' ; LC: '{' ; RC: '}' ; -COLON: ':' ; SEMICOLON: ';' ; DOT: '.' ; COMMA: ',' ; -ASSIGNMENT: '=' ; - -ASSIGNMENT_OP: '+=' | '-=' | '*=' | '**=' | '/=' | '\\=' | '%=' | '<<=' | '>>=' | '&=' | '^=' | '|=' ; - -SELF_OP: '++' | '--' ; - -LEFT_ASSIGNMENT: '<--' | '<==' ; +UNDERSCORE: '_' ; -RIGHT_ASSIGNMENT: '-->' | '==>' ; +/*////////////////////////////////////////////////////////////// + OPERATORS +//////////////////////////////////////////////////////////////*/ -CONSTRAINT_EQ: '===' ; +TERNARY_CONDITION: '?' ; +TERNARY_ALTERNATIVE: ':' ; -QUESTION_MARK: '?' ; +EQ_CONSTRAINT: '===' ; +LEFT_CONSTRAINT: '<--' | '<==' ; +RIGHT_CONSTRAINT: '-->' | '==>' ; -UNDERSCORE: '_' ; +// Unary operators +SELF_OP: '++' | '--' ; NOT: '!' ; BNOT: '~' ; +// left to right associativity POW: '**' ; MUL: '*' ; @@ -101,24 +102,31 @@ BAND: '&' ; BXOR: '^' ; BOR: '|' ; +// Require parentheses associativity EQ: '==' ; NEQ: '!=' ; GT: '>' ; LT: '<' ; LE: '>=' ; GE: '<=' ; + +// left to right associativity AND: '&&' ; OR: '||' ; +// right to left associativity +ASSIGNMENT: '=' ; +ASSIGNMENT_WITH_OP: '+=' | '-=' | '*=' | '**=' | '/=' | '\\=' | '%=' | '<<=' | '>>=' | '&=' | '^=' | '|=' ; + ID : ID_SYMBOL* LETTER (LETTER|DIGIT|ID_SYMBOL)*; fragment LETTER : [a-zA-Z\u0080-\u00FF] ; fragment ID_SYMBOL : [_$] ; -NUMBER: DIGIT+ | HEX; // match integers +NUMBER: DIGIT+ | HEX; fragment -DIGIT: [0-9] ; // match single digit // match single letter +DIGIT: [0-9] ; HEX : '0' 'x' HEXDIGIT+ ; fragment @@ -128,7 +136,7 @@ STRING : '"' (ESC|.)*? '"' ; fragment ESC: '\\' [btnrf"\\] ; COMMENT - : '/*' .*? '*/' -> channel(HIDDEN) // match anything between /* and */ + : '/*' .*? '*/' -> channel(HIDDEN) ; LINE_COMMENT diff --git a/grammar/Circom.g4 b/grammar/CircomParser.g4 similarity index 82% rename from grammar/Circom.g4 rename to grammar/CircomParser.g4 index 4562d65..e48a8a6 100644 --- a/grammar/Circom.g4 +++ b/grammar/CircomParser.g4 @@ -1,6 +1,6 @@ -grammar Circom; +parser grammar CircomParser; -import LexerCircom; +options { tokenVocab=CircomLexer; } circuit : pragmaDeclaration* includeDeclaration* blockDeclaration* componentMainDeclaration? @@ -33,7 +33,7 @@ functionStmt : functionBlock #FuncBlock | ID arrayDimension* SELF_OP ';' #FuncSelfOp | varDeclaration ';' #FuncVarDeclaration - | identifier (ASSIGNMENT | ASSIGNMENT_OP) expression ';' #FuncAssignmentExpression + | identifier (ASSIGNMENT | ASSIGNMENT_WITH_OP) expression ';' #FuncAssignmentExpression | '(' argsWithUnderscore ')' ASSIGNMENT ('(' expressionList ')' | expression) ';' #FuncVariadicAssignment | 'if' parExpression functionStmt ('else' functionStmt)? #IfFuncStmt | 'while' parExpression functionStmt #WhileFuncStmt @@ -67,15 +67,15 @@ templateStmt | componentDeclaration ';' | blockInstantiation ';' | identifier ASSIGNMENT expression ';' - | expression CONSTRAINT_EQ expression ';' - | element (LEFT_ASSIGNMENT | ASSIGNMENT_OP) expression ';' - | '(' element (',' element)* ')' LEFT_ASSIGNMENT '(' expression (',' expression)* ')' ';' - | expression RIGHT_ASSIGNMENT element ';' - | expression RIGHT_ASSIGNMENT '(' element (',' element)* ')' ';' - | '_' (ASSIGNMENT | LEFT_ASSIGNMENT) (expression | blockInstantiation) ';' - | (expression | blockInstantiation) RIGHT_ASSIGNMENT '_' ';' - | '(' argsWithUnderscore ')' (ASSIGNMENT | LEFT_ASSIGNMENT) ('(' expressionList ')' | blockInstantiation | expression) ';' - | blockInstantiation RIGHT_ASSIGNMENT '(' argsWithUnderscore ')' ';' + | expression EQ_CONSTRAINT expression ';' + | element (LEFT_CONSTRAINT | ASSIGNMENT_WITH_OP) expression ';' + | '(' element (',' element)* ')' LEFT_CONSTRAINT '(' expression (',' expression)* ')' ';' + | expression RIGHT_CONSTRAINT element ';' + | expression RIGHT_CONSTRAINT '(' element (',' element)* ')' ';' + | '_' (ASSIGNMENT | LEFT_CONSTRAINT) (expression | blockInstantiation) ';' + | (expression | blockInstantiation) RIGHT_CONSTRAINT '_' ';' + | '(' argsWithUnderscore ')' (ASSIGNMENT | LEFT_CONSTRAINT) ('(' expressionList ')' | blockInstantiation | expression) ';' + | blockInstantiation RIGHT_CONSTRAINT '(' argsWithUnderscore ')' ';' | 'if' parExpression templateStmt ('else' templateStmt)? | 'while' parExpression templateStmt | 'for' '(' forControl ')' templateStmt @@ -89,7 +89,7 @@ forControl: forInit ';' expression ';' forUpdate ; forInit: 'var'? identifier (ASSIGNMENT rhsValue)? ; -forUpdate: ID (SELF_OP | ((ASSIGNMENT | ASSIGNMENT_OP) expression)) | SELF_OP ID ; +forUpdate: ID (SELF_OP | ((ASSIGNMENT | ASSIGNMENT_WITH_OP) expression)) | SELF_OP ID ; parExpression: '(' expression ')' ; @@ -130,7 +130,7 @@ signalDefinition: 'signal' SIGNAL_TYPE? tagList? identifier; tagList: '{' args '}' ; signalDeclaration - : signalDefinition (LEFT_ASSIGNMENT rhsValue)? + : signalDefinition (LEFT_CONSTRAINT rhsValue)? | signalDefinition (',' identifier)* ; @@ -152,8 +152,8 @@ rhsValue componentCall : '(' expressionList? ')' - | '(' ID LEFT_ASSIGNMENT expression (',' ID LEFT_ASSIGNMENT expression)* ')' - | '(' expression RIGHT_ASSIGNMENT ID (',' expression RIGHT_ASSIGNMENT ID)* ')' + | '(' ID LEFT_CONSTRAINT expression (',' ID LEFT_CONSTRAINT expression)* ')' + | '(' expression RIGHT_CONSTRAINT ID (',' expression RIGHT_CONSTRAINT ID)* ')' ; blockInstantiation: 'parallel'? ID '(' expressionList? ')' componentCall? ; diff --git a/simple_listener.go b/simple_listener.go index f85fe67..0882e05 100644 --- a/simple_listener.go +++ b/simple_listener.go @@ -9,7 +9,7 @@ import ( ) type SimpleListener struct { - *bindings.BaseCircomListener + *bindings.BaseCircomParserListener parser antlr.Parser } From 7b9319b860e77093f7740f6912c9612437e87432 Mon Sep 17 00:00:00 2001 From: Kyryl Riabov Date: Wed, 16 Oct 2024 19:09:45 +0300 Subject: [PATCH 2/3] Fixed op order --- grammar/CircomParser.g4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammar/CircomParser.g4 b/grammar/CircomParser.g4 index e48a8a6..16de660 100644 --- a/grammar/CircomParser.g4 +++ b/grammar/CircomParser.g4 @@ -102,7 +102,7 @@ expression | expression op=('+' | '-') expression #BinaryExpression | expression op=('<<' | '>>') expression #BinaryExpression | expression op=('&' | '^' | '|') expression #BinaryExpression - | expression op=('==' | '!=' | '>' | '<' | '<=' | '>=' | '&&' | '||') expression #BinaryExpression + | expression op=('==' | '!=' | '>' | '<' | '>=' | '<=' | '&&' | '||') expression #BinaryExpression | expression '?' expression ':' expression #TernaryExpression ; From 0ece9bde244e6e805a173a783f36c8e77df0848c Mon Sep 17 00:00:00 2001 From: Kyryl Riabov Date: Wed, 16 Oct 2024 19:13:40 +0300 Subject: [PATCH 3/3] Fixed LE and GE ops --- grammar/CircomLexer.g4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grammar/CircomLexer.g4 b/grammar/CircomLexer.g4 index fac543c..72e5d64 100644 --- a/grammar/CircomLexer.g4 +++ b/grammar/CircomLexer.g4 @@ -107,8 +107,8 @@ EQ: '==' ; NEQ: '!=' ; GT: '>' ; LT: '<' ; -LE: '>=' ; -GE: '<=' ; +LE: '<=' ; +GE: '>=' ; // left to right associativity AND: '&&' ;