update
This commit is contained in:
+215
-103
@@ -1,138 +1,250 @@
|
||||
start: script
|
||||
// tcl.lark
|
||||
|
||||
start: script
|
||||
script: statement*
|
||||
|
||||
statement: declaracion_funcion modulo_ppal
|
||||
statement: function_declaration
|
||||
| top_level
|
||||
|
||||
declaracion_funcion: "proc" IDENTIFICADOR "{" args_funcion "}" "{" cuerpo_funcion "}" declaracion_funcion |
|
||||
args_funcion: "{" IDENTIFICADOR "}" args_funcion |
|
||||
// --- Function declarations (zero or more) ---
|
||||
function_declaration: ("proc" IDENTIFIER "{" function_args "}" "{" function_body "}")*
|
||||
|
||||
cuerpo_funcion: declaracion cuerpo_funcion | puts cuerpo_funcion | gets ";" cuerpo_funcion | if_funcion cuerpo_funcion
|
||||
| for_funcion cuerpo_funcion | while_funcion cuerpo_funcion | switch_funcion cuerpo_funcion
|
||||
| r_return cuerpo_funcion | agrup ";" cuerpo_funcion |
|
||||
// --- Function arguments (0..n blocks) ---
|
||||
function_args: ("{" IDENTIFIER "}")*
|
||||
|
||||
if_funcion: inicio_if cuerpo_funcion "}" elseif_funcion
|
||||
elseif_funcion: inicio_elseif cuerpo_funcion "}" elseif_funcion | else_funcion
|
||||
else_funcion: inicio_else cuerpo_funcion "}" |
|
||||
// --- Function body: zero or more statements ---
|
||||
function_body: (assignment_statement
|
||||
| print_statement
|
||||
| input_statement ";"
|
||||
| if_statement
|
||||
| for_statement
|
||||
| while_statement
|
||||
| switch_statement
|
||||
| return_statement
|
||||
| grouping ";"
|
||||
)*
|
||||
|
||||
switch_funcion: inicio_switch case_funcion "}"
|
||||
case_funcion: inicio_case cuerpo_funcion "}" case2_funcion
|
||||
case2_funcion: inicio_case cuerpo_funcion "}" case2_funcion | default_funcion
|
||||
default_funcion: inicio_default cuerpo_funcion "}" |
|
||||
// --- If / elseif / else in functions ---
|
||||
if_statement: if_header function_body "}" elseif_clause
|
||||
|
||||
for_funcion: inicio_for cuerpo_loop_func "}"
|
||||
while_funcion: inicio_while cuerpo_loop_func "}"
|
||||
elseif_clause: elseif_header function_body "}" elseif_clause
|
||||
| else_clause
|
||||
|
||||
cuerpo_loop_func: r_break cuerpo_loop_func | r_continue cuerpo_loop_func | declaracion cuerpo_loop_func
|
||||
| gets ";" cuerpo_loop_func | puts cuerpo_loop_func | r_return cuerpo_loop_func
|
||||
| if_loop_func cuerpo_loop_func | switch_loop_func cuerpo_loop_func | for_funcion cuerpo_loop_func
|
||||
| while_funcion cuerpo_loop_func | agrup ";" cuerpo_loop_func |
|
||||
else_clause: else_header function_body "}"
|
||||
| /* empty */
|
||||
|
||||
if_loop_func: inicio_if cuerpo_loop_func "}" elseif_loop_func
|
||||
elseif_loop_func: inicio_elseif cuerpo_loop_func "}" elseif_loop_func | else_loop_func
|
||||
else_loop_func: inicio_else cuerpo_loop_func "}" |
|
||||
// --- Switch in functions ---
|
||||
switch_statement: switch_header case_clause "}"
|
||||
|
||||
switch_loop_func: inicio_switch case_loop_func "}"
|
||||
case_loop_func: inicio_case cuerpo_loop_func "}" case2_loop_func
|
||||
case2_loop_func: inicio_case cuerpo_loop_func "}" case2_loop_func | default_loop_func
|
||||
default_loop_func: inicio_default cuerpo_loop_func "}" |
|
||||
case_clause: case_header function_body "}" case_clauses
|
||||
|
||||
modulo_ppal: declaracion modulo_ppal | r_for modulo_ppal | gets ";" modulo_ppal | r_if modulo_ppal
|
||||
| puts modulo_ppal | r_while modulo_ppal | r_switch modulo_ppal | agrup ";" modulo_ppal |
|
||||
case_clauses: case_header function_body "}" case_clauses
|
||||
| default_clause
|
||||
|
||||
r_if: inicio_if cuerpo_inst "}" elseif
|
||||
elseif: inicio_elseif cuerpo_inst "}" elseif | r_else
|
||||
r_else: inicio_else cuerpo_inst "}" |
|
||||
default_clause: default_header function_body "}"
|
||||
| /* empty */
|
||||
|
||||
r_switch: inicio_switch r_case "}"
|
||||
r_case: inicio_case cuerpo_inst "}" case2
|
||||
case2: inicio_case cuerpo_inst "}" case2 | r_default
|
||||
r_default: inicio_default cuerpo_inst "}" |
|
||||
// --- For / While in functions ---
|
||||
for_statement: for_header loop_body_in_function "}"
|
||||
while_statement: while_header loop_body_in_function "}"
|
||||
|
||||
cuerpo_inst: declaracion cuerpo_inst | r_for cuerpo_inst | gets ";" cuerpo_inst | r_if cuerpo_inst
|
||||
| puts cuerpo_inst | r_while cuerpo_inst | r_switch cuerpo_inst | agrup ";" cuerpo_inst |
|
||||
|
||||
r_for: inicio_for cuerpo_loop "}"
|
||||
r_while: inicio_while cuerpo_loop "}"
|
||||
loop_body_in_function: (break_statement
|
||||
| continue_statement
|
||||
| assignment_statement
|
||||
| input_statement ";"
|
||||
| print_statement
|
||||
| return_statement
|
||||
| if_loop_statement
|
||||
| switch_loop_statement
|
||||
| for_statement
|
||||
| while_statement
|
||||
| grouping ";"
|
||||
)*
|
||||
|
||||
cuerpo_loop: declaracion cuerpo_loop | r_for cuerpo_loop | gets ";" cuerpo_loop | if_loop cuerpo_loop
|
||||
| puts cuerpo_loop | r_while cuerpo_loop | switch_loop cuerpo_loop | r_break cuerpo_loop
|
||||
| r_continue cuerpo_loop | agrup ";" cuerpo_loop |
|
||||
|
||||
if_loop: inicio_if cuerpo_loop "}" elseif_loop
|
||||
elseif_loop: inicio_elseif cuerpo_loop "}" elseif_loop | else_loop
|
||||
else_loop: inicio_else cuerpo_loop "}" |
|
||||
if_loop_statement: if_header loop_body_in_function "}" elseif_loop_clause
|
||||
|
||||
switch_loop: inicio_switch case_loop "}"
|
||||
case_loop: inicio_case cuerpo_loop "}" case2_loop
|
||||
case2_loop: inicio_case cuerpo_loop "}" case2_loop | default_loop
|
||||
default_loop: inicio_default cuerpo_loop "}" |
|
||||
elseif_loop_clause: elseif_header loop_body_in_function "}" elseif_loop_clause
|
||||
| else_loop_clause
|
||||
|
||||
puts: "puts" asignacion ";"
|
||||
gets: "gets" "stdin"
|
||||
declaracion: "set" IDENTIFICADOR indice asignacion ";"
|
||||
else_loop_clause: else_header loop_body_in_function "}"
|
||||
| /* empty */
|
||||
|
||||
agrup: "[" aux_agrup
|
||||
aux_agrup: expr "]" | IDENTIFICADOR param_func "]" | gets "]" | "array" aux_array
|
||||
aux_array: "size" IDENTIFICADOR "]" | "exists" IDENTIFICADOR "]"
|
||||
switch_loop_statement: switch_header case_loop_clause "}"
|
||||
|
||||
param_func: "{" aux_param |
|
||||
aux_param: asignacion "}" param_func | expr "}" param_func
|
||||
case_loop_clause: case_header loop_body_in_function "}" case_loop_clauses
|
||||
|
||||
asignacion: valor | "$" IDENTIFICADOR indice | agrup
|
||||
case_loop_clauses: case_header loop_body_in_function "}" case_loop_clauses
|
||||
| default_loop_clause
|
||||
|
||||
indice: "(" val_indice ")" |
|
||||
val_indice: valor | agrup | "$" IDENTIFICADOR indice
|
||||
default_loop_clause: default_header loop_body_in_function "}"
|
||||
| /* empty */
|
||||
|
||||
valor: VALOR_STRING | VALOR_ENTERO | VALOR_DOUBLE
|
||||
// --- Top-level (module) statements (zero or more) ---
|
||||
top_level: (assignment_statement
|
||||
| for_main
|
||||
| input_statement ";"
|
||||
| if_main
|
||||
| print_statement
|
||||
| while_main
|
||||
| switch_main
|
||||
| grouping ";"
|
||||
)*
|
||||
|
||||
incremento: VALOR_ENTERO |
|
||||
// --- If / Else at top level ---
|
||||
if_main: if_header main_body "}" elseif_main_clause
|
||||
|
||||
r_break: "break" ";"
|
||||
r_continue: "continue" ";"
|
||||
r_return: "return" value_return ";"
|
||||
value_return: asignacion |
|
||||
elseif_main_clause: elseif_header main_body "}" elseif_main_clause
|
||||
| else_main_clause
|
||||
|
||||
expr: "expr" "{" expresion "}"
|
||||
asig_for: VALOR_ENTERO | "$" IDENTIFICADOR indice | expr
|
||||
else_main_clause: else_header main_body "}"
|
||||
| /* empty */
|
||||
|
||||
inicio_if: "if" "{" expresion "}" "then" "{"
|
||||
inicio_elseif: "elseif" "{" expresion "}" "then" "{"
|
||||
inicio_else: "else" "{"
|
||||
inicio_switch: "switch" "$" IDENTIFICADOR indice "{"
|
||||
inicio_case: "case" VALOR_ENTERO "{"
|
||||
inicio_default: "default" "{"
|
||||
main_body: (assignment_statement
|
||||
| for_main
|
||||
| input_statement ";"
|
||||
| if_main
|
||||
| print_statement
|
||||
| while_main
|
||||
| switch_main
|
||||
| grouping ";"
|
||||
)*
|
||||
|
||||
inicio_for: "for" "{" dec_for "}" "{" expresion "}" "{" "incr" IDENTIFICADOR incremento "}" "{"
|
||||
dec_for: "set" IDENTIFICADOR asig_for
|
||||
// --- Switch at top level ---
|
||||
switch_main: switch_header main_case_clause "}"
|
||||
|
||||
inicio_while : "while" "{" expresion "}" "{"
|
||||
main_case_clause: case_header main_body "}" main_case_clauses
|
||||
|
||||
expresion: exp_or
|
||||
exp_or: exp_or "||" exp_and | exp_and
|
||||
exp_and: exp_and "&&" exp_ig | exp_ig
|
||||
exp_ig: exp_ig op_ig exp_rel | exp_rel
|
||||
exp_rel: exp_rel op_rel exp_add | exp_add
|
||||
exp_add: exp_add op_add exp_mul | exp_mul
|
||||
exp_mul: exp_mul op_mul exp_pot | exp_pot
|
||||
exp_pot: exp_pot "**" exp_una | exp_una
|
||||
exp_una: op_una exp_una | term
|
||||
term: "$" IDENTIFICADOR indice | agrup | valor | "(" exp_or ")"
|
||||
main_case_clauses: case_header main_body "}" main_case_clauses
|
||||
| default_main_clause
|
||||
|
||||
op_ig: "eq" | "==" | "ne" | "!="
|
||||
op_rel: ">" | "<" | ">=" | "<="
|
||||
op_add: "+" | "-"
|
||||
op_mul: "*" | "/" | "%"
|
||||
op_una: "-" | "!"
|
||||
default_main_clause: default_header main_body "}"
|
||||
| /* empty */
|
||||
|
||||
// --- For / While at top level ---
|
||||
for_main: for_header main_loop_body "}"
|
||||
while_main: while_header main_loop_body "}"
|
||||
|
||||
IDENTIFICADOR: /[a-zA-Z_][a-zA-Z0-9_]*/
|
||||
VALOR_ENTERO: /'-'?[0-9]+/
|
||||
VALOR_DOUBLE: /[0-9]+ '.' [0-9]+/
|
||||
VALOR_STRING: /'"' ~[\r\n"]* '"'/
|
||||
main_loop_body: (assignment_statement
|
||||
| for_main
|
||||
| input_statement ";"
|
||||
| if_loop_main
|
||||
| print_statement
|
||||
| while_main
|
||||
| switch_loop_main
|
||||
| break_statement
|
||||
| continue_statement
|
||||
| grouping ";"
|
||||
)*
|
||||
|
||||
if_loop_main: if_header main_loop_body "}" elseif_loop_main
|
||||
|
||||
elseif_loop_main: elseif_header main_loop_body "}" elseif_loop_main
|
||||
| else_loop_main
|
||||
|
||||
else_loop_main: else_header main_loop_body "}"
|
||||
| /* empty */
|
||||
|
||||
switch_loop_main: switch_header case_loop_main "}"
|
||||
|
||||
case_loop_main: case_header main_loop_body "}" case_loop_main_clauses
|
||||
|
||||
case_loop_main_clauses: case_header main_loop_body "}" case_loop_main_clauses
|
||||
| default_loop_main
|
||||
|
||||
default_loop_main: default_header main_loop_body "}"
|
||||
| /* empty */
|
||||
|
||||
// --- Primitive statements ---
|
||||
print_statement: "puts" assignment ";"
|
||||
input_statement: "gets" "stdin"
|
||||
assignment_statement: "set" IDENTIFIER index access_value ";"
|
||||
|
||||
grouping: "[" grouping_aux "]"
|
||||
grouping_aux: expression
|
||||
| IDENTIFIER function_param
|
||||
| input_statement
|
||||
| "array" array_aux
|
||||
|
||||
array_aux: "size" IDENTIFIER
|
||||
| "exists" IDENTIFIER
|
||||
|
||||
function_param: "{" param_aux "}"
|
||||
param_aux: assignment_value
|
||||
| expression
|
||||
|
||||
assignment_value: value
|
||||
| "$" IDENTIFIER index
|
||||
| grouping
|
||||
|
||||
index: "(" index_value ")"
|
||||
index_value: value
|
||||
| grouping
|
||||
| "$" IDENTIFIER index
|
||||
|
||||
value: STRING_LITERAL
|
||||
| INT
|
||||
| FLOAT
|
||||
|
||||
increment: INT?
|
||||
|
||||
break_statement: "break" ";"
|
||||
continue_statement: "continue" ";"
|
||||
return_statement: "return" return_value ";"
|
||||
return_value: assignment_value?
|
||||
|
||||
expr_command: "expr" "{" expression "}"
|
||||
for_init: INT
|
||||
| "$" IDENTIFIER index
|
||||
| expr_command
|
||||
|
||||
// --- Headers for control structures ---
|
||||
if_header: "if" "{" expression "}" "then" "{"
|
||||
elseif_header: "elseif" "{" expression "}" "then" "{"
|
||||
else_header: "else" "{"
|
||||
switch_header: "switch" "$" IDENTIFIER index "{"
|
||||
case_header: "case" INT "{"
|
||||
default_header: "default" "{"
|
||||
for_header: "for" "{" for_declaration "}" "{" expression "}" "{" "incr" IDENTIFIER increment "}" "{"
|
||||
for_declaration: "set" IDENTIFIER for_init
|
||||
while_header: "while" "{" expression "}" "{"
|
||||
|
||||
// --- Expression grammar ---
|
||||
expression: or_expression
|
||||
or_expression: or_expression "||" and_expression
|
||||
| and_expression
|
||||
and_expression: and_expression "&&" equality_expression
|
||||
| equality_expression
|
||||
equality_expression: equality_expression eq_ops relational_expression
|
||||
| relational_expression
|
||||
relational_expression: relational_expression rel_ops additive_expression
|
||||
| additive_expression
|
||||
additive_expression: additive_expression add_ops multiplicative_expression
|
||||
| multiplicative_expression
|
||||
multiplicative_expression: multiplicative_expression mul_ops power_expression
|
||||
| power_expression
|
||||
power_expression: power_expression "**" unary_expression
|
||||
| unary_expression
|
||||
unary_expression: unary_ops unary_expression
|
||||
| term
|
||||
term: "$" IDENTIFIER index
|
||||
| grouping
|
||||
| value
|
||||
| "(" or_expression ")"
|
||||
|
||||
eq_ops: "eq" | "==" | "ne" | "!="
|
||||
rel_ops: ">" | "<" | ">=" | "<="
|
||||
add_ops: "+" | "-"
|
||||
mul_ops: "*" | "/" | "%"
|
||||
unary_ops: "-" | "!"
|
||||
|
||||
// --- Terminals ---
|
||||
IDENTIFIER: /[a-zA-Z_][a-zA-Z0-9_]*/
|
||||
INT: /-?[0-9]+/
|
||||
FLOAT: /[0-9]+\.[0-9]+/
|
||||
STRING_LITERAL: /"([^"\\]|\\.)*"/
|
||||
COMMENT: /#[^\r\n]*/
|
||||
WS: /[ \t]+/
|
||||
NEWLINE: /\r?\n/
|
||||
|
||||
%ignore WS
|
||||
%ignore COMMENT
|
||||
|
||||
%ignore /[ \t]+/ // spaces & tabs
|
||||
%ignore COMMENT
|
||||
%ignore _NL
|
||||
Reference in New Issue
Block a user