--
-- Copyright (c) 2002 Kenneth James Stauffer
--
%{
class AM_PARSER
-- Parse the AM language.
inherit
YY_PARSER_SKELETON[ANY]
rename
make as make_parser_skeleton,
parse as yacc_parse
redefine
report_error, last_token
end
AM_TOKEN_ID
export
{NONE} all
end
AM_PT_CONSTANTS
export
{NONE} all
end
creation
make
%}
------------------------ G R A M M E R -----------------------------
--
-- Types of non-terminals
--
%type opt_header header_list
%type header
%type opt_interface interface_list
%type interface
%type opt_dlm dlm_list
%type dlm
%type variable_decl vbl_decl
%type vbl_decl_simple
%type vbl_decl_table
%type vbl_decl_field
%type vbl_decl_array
%type opt_vbl_attrs vbl_attr_list vbl_attr
%type ord_args
%type am5flg_args
%type dimensions
%type vbl_export
%type file_export
%type opt_plus
%type opt_not
%type expr factor
%type exprop assign
%type paren_expr
%type numeric_literal
%type string_literal
%type variable opt_variable
%type function
%type slice
%type opt_arglist expr_list
%type stmt stmt_basic
%type stmt_expr
%type stmt_assign
%type stmt_exefunc
%type stmt_test
%type stmt_proc
%type stmt_succeed
%type stmt_fail
%type stmt_restart
%type stmt_quit
%type stmt_initvar
%type stmt_comment
%type stmt_sql
%type stmt_form form_attr_list
%type stmt_conclusion
%type stmt_yield
%type procedure_decl proc_body
%type proc_type proc_export
%type comment
%type comments opt_comments
%type sql_attr sqlattr_args
%type sql_attr_list
%type ctrl form_attr
%type ctrl_form5
%type ctrl_text
%type ctrl_input
%type ctrl_group
%type ctrl_radio
%type ctrl_enter
%type ctrl_hscrol
%type ctrl_output
%type ctrl_combo
%type ctrl_vscrol
%type ctrl_button
%type ctrl_help
%type ctrl_mclist
%type ctrl_check
%type ctrl_cancel
%type ctrl_list
%type ctrl_multi
%type ctrl_ocx
%type ctrl_attr
%type ctrl_args
%type disp_args
%type col_args
%type number
%type font_name
%type opt_text_string
%type hlpid_args
--
-- Tokens
--
--
-- token codes 0 - 255 are ascii values for single character tokens
--
%token '*'
%token ':'
%token '['
%token ']'
%token '{'
%token '}'
%token '('
%token ')'
%token '+'
%token '/'
%token '!'
%token '-'
%token '|'
%token '&'
%token '#'
%token ','
%token '.'
%token '^'
%token TK_NL
--
-- Misc. tokens
--
%token TK_COMMENT_STRING
%token TK_FILENAME
%token TK_INTEGER
%token TK_PROCNAME
%token TK_TEXT_STRING
--
-- All keyword tokens are represented using TKW_XXXXXX
-- misc. keywords
--
%token TKW_INTERFACE
%token TKW_DLM
%token TKW_AND
%token TKW_OR
%token TKW_NOT
%token TKW_IF
--
-- keywords for export status
--
%token TKW_PR
%token TKW_PUB
%token TKW_EXT
%token TKW_RL
%token TKW_EX
--
-- keywords surrounded by square brackets
--
%token TKW_VBL
%token TKW_MEN
%token TKW_ACCL
%token TKW_MIT
%token TKW_PROC
%token TKW_MSB
%token TKW_FRAME
--
-- tokens for the DO
--
%token TK_DO_ASSIGN_VARIABLE
%token TK_DO_EXECUTE_FUNCTION
%token TK_DO_TEST_EXPRESSION
%token TK_DO_SUCCEED
%token TK_DO_FAIL
%token TK_DO_SQL_REQUEST
%token TK_DO_PMFORM
%token TK_DO_RESTART
%token TK_DO_QUIT
%token TK_DO_INIT_VARIABLES
%token TK_DO_COMMENT
%token TK_DO_CONCLUSION_DISPLAY
%token TK_DO_YIELD
--
-- syntax tokens
--
%token TK_PLUSPLUS
%token TK_PLUS
%token TK_PLUS4
--
-- Form attributes
--
%token TKA_FORM5
%token TKA_TEXT
%token TKA_LEN
%token TKA_DISP
%token TKA_INPUT
%token TKA_EX
%token TKA_DECPL
%token TKA_GROUP
%token TKA_BUTEX
%token TKA_RADIO
%token TKA_ENTER
%token TKA_HSCROL
%token TKA_UDC
%token TKA_NPOS
%token TKA_HLPID
%token TKA_HELPF
%token TKA_OUTPUT
%token TKA_PROC
%token TKA_LTYP
%token TKA_LIST
%token TKA_COMBO
%token TKA_VSCROL
%token TKA_COL
%token TKA_BUTTON
%token TKA_HELP
%token TKA_MCLIST
%token TKA_LBSEL
%token TKA_LBNUM
%token TKA_CLORD
%token TKA_CHECK
%token TKA_DBL
%token TKA_CANCEL
%token TKA_MULTI
%token TKA_TIPTXT
%token TKA_HLPCTX
%token TKA_TIPPRC
%token TKA_OCX
%token TKA_OXTITL
%token TKA_OXLTIT
%token TKA_OXFLGS
%token TKA_OXCLSX
%token TKA_OXPROP
%token TKA_OXDATA
--
-- frame attributes (TKA_xxxxx) (can also appear in PmForm?)
--
%token TKA_TITLE
%token TKA_BACK
%token TKA_TBINF
%token TKA_ICON
--
-- sql attributes
--
%token TKA_SQLARRAY
%token TKA_SQLATTR
%token TKA_REQSQL
%token TKA_REQEXP
--
-- variable attributes (TKV_xxxxxx)
--
%token TKV_OSTY
%token TKV_OCSTY
%token TKV_AM5FLG
%token TKV_AM3FLG
%token TKV_IFMT
%token TKV_ICFMT
%token TKV_VAL
%token TKV_ERRS
%token TKV_ORD
%token TKV_CMNT
--
-- tokens that appear inside regular language constructs
--
%token TK_IDENTIFIER
%token TK_NUMBER
%token TK_STRING
%token TK_LE
%token TK_LT
%token TK_GE
%token TK_GT
%token TK_ASSIGN
%token TK_NE
%token TK_EQ
--
-- an identifier with embedded question marks
--
%token TK_FONTNAME
--
-- a hex literal
--
%token TK_HEX
--
-- operators precedence
--
%right TKW_OR
%right TKW_AND
%left '|'
%left '&'
%left TK_EQ TK_NE TK_GT TK_GE TK_LT TK_LE
%left '+' '-'
%left '*' '/'
%left '^'
%nonassoc '!'
%nonassoc TK_UNIMINUS
%start program
%%
program : opt_header opt_interface opt_dlm entity_list
{
parse_tree.set_header($1);
parse_tree.set_interface($2);
parse_tree.set_dlm($3);
}
;
entity_list : entity
| entity_list entity
;
entity : procedure_decl { parse_tree.add_procedure($1); }
| variable_decl { parse_tree.add_variable($1); }
| menu_decl
| frame_decl
;
opt_header : header_list { $$ := $1; }
| -- empty --
{ $$ := Void; }
;
header_list : header { !! $$.make($1); }
| header_list header {
$1.extend($2);
$$ := $1;
}
;
header : '*' TK_COMMENT_STRING TK_NL { !! $$.make($1, $2); }
| '*' TK_NL { !! $$.make($1, Void); }
;
opt_interface : interface_list { $$ := $1; }
| -- empty --
{ $$ := Void; }
;
interface_list : interface { !! $$.make($1); }
| interface_list interface
{
$1.extend($2);
$$ := $1;
}
;
interface : TKW_INTERFACE ':' TK_IDENTIFIER TK_NL
{ !! $$.make($1, $3); }
;
opt_dlm : dlm_list { $$ := $1; }
| -- empty --
{ $$ := Void; }
;
dlm_list : dlm { !! $$.make($1); }
| dlm_list dlm
{
$1.extend($2);
$$ := $1;
}
;
dlm : TKW_DLM ':' TK_FILENAME TK_INTEGER TK_NL
{ !! $$.make($1, $3, $4); }
;
procedure_decl : '[' TK_INTEGER ']' TK_PROCNAME
proc_type file_export proc_export TK_NL opt_comments proc_body
{
$10.set_rest($2, $4, $5, $6, $7, $9);
$$ := $10;
}
;
proc_type : TKW_PR { $$ := Ampt_pr; }
| TKW_RL { $$ := Ampt_rl; }
;
proc_export : TKW_EXT { $$ := Ampt_ext; }
| TKW_PUB { $$ := Ampt_pub; }
| -- empty --
{ $$ := Ampt_none; }
;
opt_comments : comments { $$ := $1; }
| -- empty --
{ $$ := Void; }
;
comments : comment { !! $$.make($1); }
| comments comment { $1.extend($2); $$ := $1; }
;
comment : TK_PLUS4 TK_COMMENT_STRING TK_NL
{ !! $$.make($2); }
;
proc_body : TK_PLUSPLUS stmt { !! $$.make($1, $2); }
| TKW_IF stmt { !! $$.make($1, $2); }
| -- empty --
{ !! $$.make_empty; }
;
stmt : stmt_expr { $$ := $1; }
| stmt_basic { $$ := $1; }
;
stmt_expr : stmt TKW_OR stmt { !! $$.make($2, $1, $3); }
| stmt TKW_AND stmt { !! $$.make($2, $1, $3); }
;
stmt_basic : stmt_assign { $$ := $1; }
| stmt_exefunc { $$ := $1; }
| stmt_test { $$ := $1; }
| stmt_proc { $$ := $1; }
| stmt_succeed { $$ := $1; }
| stmt_fail { $$ := $1; }
| stmt_restart { $$ := $1; }
| stmt_quit { $$ := $1; }
| stmt_initvar { $$ := $1; }
| stmt_comment { $$ := $1; }
| stmt_sql { $$ := $1; }
| stmt_form { $$ := $1; }
| stmt_conclusion { $$ := $1; }
| stmt_yield { $$ := $1; }
;
stmt_assign : TK_DO_ASSIGN_VARIABLE TK_NL assign TK_NL
{ !! $$.make($3); }
;
stmt_exefunc : TK_DO_EXECUTE_FUNCTION TK_NL expr TK_NL
{ !! $$.make($3); }
;
stmt_test : TK_DO_TEST_EXPRESSION TK_NL expr TK_NL
{ !! $$.make($3); }
;
stmt_proc : opt_plus '[' TK_INTEGER ']' opt_not TK_PROCNAME TK_NL
{ !! $$.make($1, $5, $3, $6); }
;
stmt_succeed : TK_DO_SUCCEED TK_NL
{ !! $$.make($1); }
;
stmt_fail : TK_DO_FAIL TK_NL
{ !! $$.make($1); }
;
stmt_restart : TK_DO_RESTART TK_NL
{ !! $$.make($1); }
;
stmt_quit : TK_DO_QUIT TK_NL
{ !! $$.make($1); }
;
stmt_initvar : TK_DO_INIT_VARIABLES TK_NL
{ !! $$.make($1); }
;
stmt_comment : TK_DO_COMMENT TK_NL TK_COMMENT_STRING TK_NL
{ !! $$.make($3); }
;
stmt_sql : TK_DO_SQL_REQUEST TK_NL sql_attr_list
{ !! $$.make($1, $3); }
;
stmt_form : TK_DO_PMFORM TK_NL form_attr_list
{
$3.set_pos($1);
$$ := $3;
}
;
stmt_conclusion : TK_DO_CONCLUSION_DISPLAY TK_NL
{ !! $$.make($1); }
;
stmt_yield : TK_DO_YIELD TK_NL
{ !! $$.make($1); }
;
sql_attr_list : sql_attr TK_NL { !! $$.make; $$.extend($1); }
| sql_attr_list sql_attr TK_NL { $1.extend($2); $$ := $1; }
;
sql_attr : ':' TKA_SQLARRAY ':' opt_variable
{ !! $$.make_sqlarray($4); }
| ':' TKA_SQLATTR ':' sqlattr_args
{ $$ := $4; }
| ':' TKA_REQSQL ':' TK_TEXT_STRING
{ !! $$.make_reqsql($4); }
| ':' TKA_REQEXP ':' expr
{ !! $$.make_reqexp($4); }
;
form_attr_list : form_attr TK_NL { !! $$.make($1); }
| form_attr_list form_attr TK_NL
{
$1.add_ctrl($2);
$$ := $1;
}
;
form_attr : ctrl { $$ := $1; }
| ctrl_attr { $$ := $1; }
;
ctrl : ctrl_form5 { $$ := $1; }
| ctrl_text { $$ := $1; }
| ctrl_input { $$ := $1; }
| ctrl_group { $$ := $1; }
| ctrl_radio { $$ := $1; }
| ctrl_enter { $$ := $1; }
| ctrl_hscrol { $$ := $1; }
| ctrl_output { $$ := $1; }
| ctrl_combo { $$ := $1; }
| ctrl_vscrol { $$ := $1; }
| ctrl_button { $$ := $1; }
| ctrl_help { $$ := $1; }
| ctrl_mclist { $$ := $1; }
| ctrl_check { $$ := $1; }
| ctrl_cancel { $$ := $1; }
| ctrl_list { $$ := $1; }
| ctrl_multi { $$ := $1; }
| ctrl_ocx { $$ := $1; }
;
ctrl_attr : ':' '+' TKA_TEXT ':' opt_text_string { !! $$.make_str($3, $5); }
| ':' '+' TKA_LEN ':' expr { !! $$.make_expr($3, $5); }
| ':' '+' TKA_DISP ':' disp_args { !! $$.make_disp($3, $5); }
| ':' '+' TKA_EX ':' expr { !! $$.make_expr($3, $5); }
| ':' '+' TKA_DECPL ':' number { !! $$.make_str($3, $5); }
| ':' '+' TKA_BUTEX ':' expr { !! $$.make_expr($3, $5); }
| ':' '+' TKA_UDC ':' opt_text_string { !! $$.make_str($3, $5); }
| ':' '+' TKA_NPOS ':' expr { !! $$.make_expr($3, $5); }
| ':' '+' TKA_HLPID ':' hlpid_args { !! $$.make_str($3, $5); }
| ':' '+' TKA_PROC ':' TK_PROCNAME { !! $$.make_str($3, $5.value); }
| ':' '+' TKA_LTYP ':' number { !! $$.make_str($3, $5); }
| ':' '+' TKA_LIST ':' variable { !! $$.make_var($3, $5); }
| ':' '+' TKA_LBSEL ':' variable { !! $$.make_var($3, $5); }
| ':' '+' TKA_LBNUM ':' variable { !! $$.make_var($3, $5); }
| ':' '+' TKA_DBL ':' TK_PROCNAME { !! $$.make_str($3, $5.value); }
| ':' '+' TKA_TIPTXT ':' expr { !! $$.make_expr($3, $5); }
| ':' '+' TKA_CLORD ':' opt_text_string { !! $$.make_str($3, $5); }
| ':' '+' TKA_HLPCTX ':' opt_text_string { !! $$.make_str($3, $5); }
| ':' '+' TKA_TIPPRC ':' TK_PROCNAME { !! $$.make_str($3, $5.value); }
| ':' '-' TKA_COL col_args { !! $$.make_col($3, $4); }
| ':' '+' TKA_OXTITL ':' opt_text_string { !! $$.make_str($3, $5); }
| ':' '+' TKA_OXLTIT ':' opt_text_string { !! $$.make_str($3, $5); }
| ':' '+' TKA_OXFLGS ':' opt_text_string { !! $$.make_str($3, $5); }
| ':' '+' TKA_OXCLSX ':' opt_text_string { !! $$.make_str($3, $5); }
| ':' '+' TKA_OXPROP ':' number { !! $$.make_str($3, $5); }
| ':' '+' TKA_OXDATA ':' opt_text_string { !! $$.make_str($3, $5); }
;
ctrl_form5 : ':' TKA_FORM5 ':' ctrl_args { !! $$.make($4); }
;
ctrl_text : ':' TKA_TEXT ':' ctrl_args { !! $$.make($4); }
;
ctrl_input : ':' TKA_INPUT ':' ctrl_args { !! $$.make($4); }
;
ctrl_group : ':' TKA_GROUP ':' ctrl_args { !! $$.make($4); }
;
ctrl_radio : ':' TKA_RADIO ':' ctrl_args { !! $$.make($4); }
;
ctrl_enter : ':' TKA_ENTER ':' ctrl_args { !! $$.make($4); }
;
ctrl_hscrol : ':' TKA_HSCROL ':' ctrl_args { !! $$.make($4); }
;
ctrl_output : ':' TKA_OUTPUT ':' ctrl_args { !! $$.make($4); }
;
ctrl_combo : ':' TKA_COMBO ':' ctrl_args { !! $$.make($4); }
;
ctrl_vscrol : ':' TKA_VSCROL ':' ctrl_args { !! $$.make($4); }
;
ctrl_button : ':' TKA_BUTTON ':' ctrl_args { !! $$.make($4); }
;
ctrl_help : ':' TKA_HELP ':' ctrl_args { !! $$.make($4); }
;
ctrl_mclist : ':' TKA_MCLIST ':' ctrl_args { !! $$.make($4); }
;
ctrl_check : ':' TKA_CHECK ':' ctrl_args { !! $$.make($4); }
;
ctrl_cancel : ':' TKA_CANCEL ':' ctrl_args { !! $$.make($4); }
;
ctrl_list : ':' TKA_LIST ':' ctrl_args { !! $$.make($4); }
;
ctrl_multi : ':' TKA_MULTI ':' ctrl_args { !! $$.make($4); }
;
ctrl_ocx : ':' TKA_OCX ':' ctrl_args { !! $$.make($4); }
;
variable_decl : '[' TKW_VBL ']' vbl_decl file_export vbl_export TK_NL opt_vbl_attrs
{
$4.set_export_mode($6);
$4.set_file_export($5);
$4.set_attrs($8);
$$ := $4;
}
;
vbl_decl : vbl_decl_simple { $$ := $1; }
| vbl_decl_table { $$ := $1; }
| vbl_decl_field { $$ := $1; }
| vbl_decl_array { $$ := $1; }
;
vbl_decl_simple : TK_IDENTIFIER { !! $$.make($1); }
;
vbl_decl_table : TK_IDENTIFIER '{' TK_NUMBER ',' TK_NUMBER '}'
{ !! $$.make($1, $3, $5, $6); }
;
vbl_decl_field : TK_IDENTIFIER '{' '#' '}' '.' TK_IDENTIFIER
{ !! $$.make($1, $6); }
;
vbl_decl_array : TK_IDENTIFIER '[' dimensions ']'
{ !! $$.make($1, $3, $4); }
;
dimensions : TK_NUMBER { !! $$.make($1); }
| dimensions ',' TK_NUMBER
{
$1.extend($3.value);
$$ := $1;
}
;
vbl_export : TKW_PUB { $$ := Ampt_pub; }
| TKW_EXT { $$ := Ampt_ext; }
| -- empty --
{ $$ := Ampt_none; }
;
opt_vbl_attrs : vbl_attr_list { $$ := $1; }
| -- empty --
{ $$ := Void; }
;
vbl_attr_list : vbl_attr TK_NL { $$ := $1; }
| vbl_attr_list vbl_attr TK_NL { $1.merge($2); $$ := $1; }
;
vbl_attr : TKV_VAL ':' expr
{
!! $$.make;
$$.set_val($3);
}
| TKV_IFMT ':' TK_TEXT_STRING
{
!! $$.make;
$$.set_ifmt($3.value);
}
| TKV_ICFMT ':' TK_TEXT_STRING
{
!! $$.make;
$$.set_icfmt($3.value);
}
| TKV_OSTY ':' TK_TEXT_STRING
{
!! $$.make;
$$.set_osty($3.value);
}
| TKV_OCSTY ':' TK_TEXT_STRING
{
!! $$.make;
$$.set_ocsty($3.value);
}
| TKV_ERRS ':' opt_text_string
{
!! $$.make;
$$.set_errs($3);
}
| TKV_ORD ':' ord_args
{
!! $$.make;
$$.set_ord($3);
}
| TKV_CMNT ':' opt_text_string
{
!! $$.make;
$$.set_cmnt($3);
}
| TKV_AM5FLG ':' am5flg_args
{
!! $$.make;
$$.set_am5flg($3);
}
| TKV_AM3FLG ':' number
{
!! $$.make;
$$.set_am3flg($3);
}
;
menu_decl : '[' TKW_MEN ']' TK_TEXT_STRING TK_NL
| '[' TKW_MIT ']' TK_TEXT_STRING TK_NL
| '[' TKW_MSB ']' TK_TEXT_STRING TK_NL
| '[' TKW_ACCL ']' accl_args TK_NL
| '[' TKW_PROC ']' TK_PROCNAME TK_NL
;
frame_decl : '[' TKW_FRAME ']' frame_args TK_NL frame_attr_list
;
frame_attr_list : frame_attr TK_NL
| frame_attr_list frame_attr TK_NL
;
frame_attr : '+' TKA_TITLE title_args
| '+' TKA_ICON TK_FILENAME
| '+' TKA_TBINF tbinf_args
| '+' TKA_BACK TK_FILENAME
| '+' TKA_HLPID hlpid_args
| '+' TKA_HELPF variable
;
-----------------------------------------------------------
------------------ ARGUMENT LISTS -------------------------
-----------------------------------------------------------
accl_args : number ',' number ',' number
;
frame_args : number ',' number ',' number ',' number ',' number ','
number ',' number ',' number
;
title_args : expr
;
tbinf_args : number ',' number
;
hlpid_args : number { $$ := $1; }
| TK_HEX { $$ := $1.value; }
;
ctrl_args : number ',' number ',' number ',' number ',' number ','
number ',' number
{ !! $$.make($1, $3, $5, $7, $9, $11, $13); }
;
disp_args : number ',' number ',' number ','
number ',' number ',' number
',' number ',' number ',' number ','
font_name ',' number ',' number
{ !! $$.make($1, $3, $5, $7, $9, $11, $13, $15,
$17, $19, $21, $23); }
;
col_args : variable ',' number ',' number
{ !! $$.make($1, $3, $5); }
;
sqlattr_args : number ',' number ',' number ',' number ',' number
{ !! $$.make_sqlattr($1, $3, $5, $7, $9); }
;
am5flg_args : number ',' number ',' number ',' number ',' number ',' number
{ !! $$.make($1, $3, $5, $7, $9, $11); }
;
ord_args : variable ',' number ',' number
{ !! $$.make($1, $3, $5); }
;
-----------------------------------------------------------
------------------ SIMPLE PRODUCTIONS ---------------------
-----------------------------------------------------------
file_export : TKW_EX { $$ := Ampt_ex; }
| -- empty --
{ $$ := Ampt_none; }
;
opt_plus : TK_PLUS { $$ := Ampt_plus; }
| -- empty --
{ $$ := Ampt_none; }
;
opt_not : TKW_NOT { $$ := True; }
| -- empty --
{ $$ := False; }
;
font_name : TK_FONTNAME { $$ := $1.value; }
| TK_IDENTIFIER { $$ := $1.value; }
;
opt_text_string : TK_TEXT_STRING { $$ := $1.value; }
| -- empty --
{ !! $$.make_from_string(""); }
;
number : TK_NUMBER { $$ := $1.value; }
| '-' TK_NUMBER
{
!! $$.make_from_string("-" + $2.value);
}
;
opt_variable : variable { $$ := $1; }
| -- empty --
{ $$ := Void; }
;
-----------------------------------------------------------
------------------ EXPRESSIONS ----------------------------
-----------------------------------------------------------
assign : variable TK_ASSIGN expr {
!! $$.make($2, $1, $3);
$1.set_lhs;
}
;
expr : exprop { $$ := $1; }
| factor { $$ := $1; }
;
exprop : expr '&' expr { !! $$.make($2, $1, $3); }
| expr '|' expr { !! $$.make($2, $1, $3); }
| expr TK_EQ expr { !! $$.make($2, $1, $3); }
| expr TK_NE expr { !! $$.make($2, $1, $3); }
| expr TK_GT expr { !! $$.make($2, $1, $3); }
| expr TK_GE expr { !! $$.make($2, $1, $3); }
| expr TK_LT expr { !! $$.make($2, $1, $3); }
| expr TK_LE expr { !! $$.make($2, $1, $3); }
| expr '+' expr { !! $$.make($2, $1, $3); }
| expr '-' expr { !! $$.make($2, $1, $3); }
| expr '*' expr { !! $$.make($2, $1, $3); }
| expr '/' expr { !! $$.make($2, $1, $3); }
| expr '^' expr { !! $$.make($2, $1, $3); }
| '!' expr { !! $$.make($1, Void, $2); }
| '-' expr %prec TK_UNIMINUS { !! $$.make($1, Void, $2); }
;
factor : paren_expr { $$ := $1; }
| numeric_literal { $$ := $1; }
| string_literal { $$ := $1; }
| variable { $$ := $1; }
| function { $$ := $1; }
| slice { $$ := $1; }
;
paren_expr : '(' expr ')' { !! $$.make($1, $3, $2); }
;
numeric_literal : TK_NUMBER { !! $$.make($1); }
;
string_literal : TK_STRING { !! $$.make($1); }
;
slice : '#' { !! $$.make($1); }
;
variable : TK_IDENTIFIER '[' expr_list ']'
{ !! $$.make_array($1, $3); }
| TK_IDENTIFIER '{' expr '}'
{ !! $$.make_table($1, $3); }
| TK_IDENTIFIER
{ !! $$.make_simple($1) }
| TK_IDENTIFIER '{' expr '}' '.' TK_IDENTIFIER
{ !! $$.make_field($1, $3, $6); }
;
function : TK_IDENTIFIER opt_arglist { !! $$.make($1, $2); }
;
opt_arglist : '(' expr_list ')' { $$ := $2; }
| '(' ')' { !! $$.make; }
;
expr_list : expr
{
!! $$.make;
$$.extend($1);
}
| expr_list ',' expr
{
$1.extend($3);
$$ := $1;
}
;
%%
make(fn: STRING) is
do
make_parser_skeleton;
!! lex.make(fn);
end
parse is
do
!! parse_tree.make;
yacc_parse;
lex.close;
if syntax_error then
parse_tree.set_parse_errors(last_error);
else
parse_tree.set_parse_errors(Void);
end
parse_tree.set_filename(lex.filename);
parse_tree.set_lines(lex.line_number);
parse_tree.set_last_modified(lex.last_modified);
ensure
parse_tree /= Void;
end
parse_tree: AM_PT_MODULE;
feature {NONE}
lex: AM_TOKENIZER;
last_error: AM_PT_PARSE_ERRORS;
report_error(a_message: STRING) is
-- print error message
do
!! last_error.make(lex.filename, lex.line_number,
lex.start_pos,
lex.end_pos,
a_message);
end
rule_error(a_message: STRING; line, spos, epos: INTEGER) is
-- my action rules will call this
-- routine to cause an error and make
-- the parser enter error recovery mode
do
!! last_error.make(lex.filename, line, spos, epos, a_message);
abort;
end
read_token is
do
check
not lex.eof;
end
lex.read_token;
if lex.failed then
!! last_error.make(lex.filename,
lex.line_number,
lex.start_pos,
lex.end_pos,
lex.last_error);
abort;
end
end
last_token: INTEGER is
do
Result := lex.last_token;
end
last_value: AM_TOKEN is
do
Result := lex.last_value;
end
end