📄 units.y
字号:
%{#include <u.h>#include <libc.h>#include <bio.h>enum{ Ndim = 15, /* number of dimensions */ Nsym = 40, /* size of a name */ Nvar = 203, /* hash table size */ Maxe = 695, /* log of largest number */};typedef struct Var Var;typedef struct Node Node;typedef struct Prefix Prefix;struct Node{ double val; schar dim[Ndim];};struct Var{ Rune name[Nsym]; Node node; Var* link;};struct Prefix{ double val; Rune* pname;};char buf[100];int digval;Biobuf* fi;Biobuf linebuf;Var* fund[Ndim];Rune line[1000];ulong lineno;int linep;int nerrors;Node one;int peekrune;Node retnode1;Node retnode2;Node retnode;Rune sym[Nsym];Var* vars[Nvar];int vflag;extern void add(Node*, Node*, Node*);extern void div(Node*, Node*, Node*);extern int specialcase(Node*, Node*, Node*);extern double fadd(double, double);extern double fdiv(double, double);extern double fmul(double, double);extern int gdigit(void*);extern Var* lookup(int);extern void main(int, char*[]);extern void mul(Node*, Node*, Node*);extern void ofile(void);extern double pname(void);extern void printdim(char*, int, int);extern int ralpha(int);extern int readline(void);extern void sub(Node*, Node*, Node*);extern int Ufmt(Fmt*);extern void xpn(Node*, Node*, int);extern void yyerror(char*, ...);extern int yylex(void);extern int yyparse(void);typedef Node* indnode;#pragma varargck type "U" indnode%}%union{ Node node; Var* var; int numb; double val;}%type <node> prog expr expr0 expr1 expr2 expr3 expr4%token <val> VAL%token <var> VAR%token <numb> SUP%%prog: ':' VAR expr { int f; f = $2->node.dim[0]; $2->node = $3; $2->node.dim[0] = 1; if(f) yyerror("redefinition of %S", $2->name); else if(vflag) print("%S\t%U\n", $2->name, &$2->node); }| ':' VAR '#' { int f, i; for(i=1; i<Ndim; i++) if(fund[i] == 0) break; if(i >= Ndim) { yyerror("too many dimensions"); i = Ndim-1; } fund[i] = $2; f = $2->node.dim[0]; $2->node = one; $2->node.dim[0] = 1; $2->node.dim[i] = 1; if(f) yyerror("redefinition of %S", $2->name); else if(vflag) print("%S\t#\n", $2->name); }| '?' expr { retnode1 = $2; }| '?' { retnode1 = one; }expr: expr4| expr '+' expr4 { add(&$$, &$1, &$3); }| expr '-' expr4 { sub(&$$, &$1, &$3); }expr4: expr3| expr4 '*' expr3 { mul(&$$, &$1, &$3); }| expr4 '/' expr3 { div(&$$, &$1, &$3); }expr3: expr2| expr3 expr2 { mul(&$$, &$1, &$2); }expr2: expr1| expr2 SUP { xpn(&$$, &$1, $2); }| expr2 '^' expr1 { int i; for(i=1; i<Ndim; i++) if($3.dim[i]) { yyerror("exponent has units"); $$ = $1; break; } if(i >= Ndim) { i = $3.val; if(i != $3.val) yyerror("exponent not integral"); xpn(&$$, &$1, i); } }expr1: expr0| expr1 '|' expr0 { div(&$$, &$1, &$3); }expr0: VAR { if($1->node.dim[0] == 0) { yyerror("undefined %S", $1->name); $$ = one; } else $$ = $1->node; }| VAL { $$ = one; $$.val = $1; }| '(' expr ')' { $$ = $2; }%%intyylex(void){ int c, i; c = peekrune; peekrune = ' ';loop: if((c >= '0' && c <= '9') || c == '.') goto numb; if(ralpha(c)) goto alpha; switch(c) { case ' ': case '\t': c = line[linep++]; goto loop; case L'脳': return '*'; case L'梅': return '/'; case L'鹿': case L'鈦
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -